According to your code, your observations, and the context you've provided in the comments, you've two issues:
- sending form data
- evaluate the response
Let's assume some basic form like this:
<form action="endpoint.php" method="post">
<input type="hidden" name="token" value="value">
<input type="submit" name="submit" value="submit">
</form>
To be able to send this form's data ourselves, we need to make sure we're intercepting the browser's default behaviour of submitting it right away as soon as the submit button is clicked (cf. also epascarello's comments):
// Intercept the onsubmit event
document.querySelector('form').onsubmit = function (evt) {
// Make sure to prevent the form from being submitted by
// the browser, which is the default behaviour.
evt.preventDefault();
// Get the form's data
let form = new FormData(evt.target);
// We're going to explicitly submitting our data
// as JSON, so make sure it actually is JSON.
let data = JSON.stringify(Object.fromEntries(form)); // https://stackoverflow.com/a/55874235/3323348
sendRequest(data); // Our submit function, which we'll define next (see below)
};
Now, we'd be able to actually send the data, and to properly handle messages and status codes send back by the server. But first, let's have a quick look at your if
clauses, because they might not work the way you expect them to. Especially because state and status aren't mutually exclusive - a readyState
of 4 doesn't mean the server hasn't answered with an HTTP status code denoting an error (like a 404):
if (xhr.readyState === 4) {
console.log(xhr.status); // Could be any HTTP status code
} else if (xhr.status === 400) {
console.log(xhr.readyState); // Could be any readyState besides 4
} else if (xhr.status != 400 && xhr.status != 200) {
console.log(xhr.readyState); // Could be any readyState besides 4...
console.log(xhr.status); // ...and any HTTP status code besides a Bad Request (400) and an OK (200)
}
So let's tackle that part a bit different, while the rest of your code stays the same (though wrapped in a function):
function sendRequest(data) {
const xhr = new XMLHttpRequest();
xhr.open('POST', '/endpoint.php'); // All requests are asynchronous by default,
// so we can drop the third parameter.
xhr.setRequestHeader('Content-Type', 'application/json');
// Since we've just created a client and initialized
// a request, we'll receive notifications for states
// 2-4 only (instead of 0-4).
xhr.onreadystatechange = function () {
console.log(xhr.readyState); // Let's watch the readyState changing
// We're interested in the final result of our request only (state 4),
// so let's jump all other states.
if (xhr.readyState !== 4) {
return;
}
const status = xhr.status; // HTTP status code
const type = status.toString().charAt(0); // Get class of HTTP status code (4xx, 5xx, ...)
if ([4,5].includes(type)) {
console.log('An error occured', status, xhr.responseText);
return;
}
if (status == 200) {
console.log('OK', xhr.responseText);
return;
}
// Server answered with a status code of 1xx, 3xx, or > 200.
console.log('Unexpected response', status, xhr.responseText);
}
xhr.send(data);
}
Now, you should be able to successfully send form data (and send it as JSON) and evaluate the HTTP response status codes. Instead of using XMLHttpRequest
, though, you might want to consider fetch()
instead.
Misc: