XMLHTTPRequest 不断循环条件语句?
XMLHTTPRequest keeps looping through conditional statements?
我正在尝试 运行 基于我 xhr
的 readystate
的条件语句。 readystate
在 open()
被调用(第 2 行)后切换到 1
,但此后永远不会改变。它会跳过条件,并且不会发送任何内容。
我很想知道为什么 readystate
没有改变?
var xhr = new XMLHttpRequest();
xhr.open('POST', submitUrl, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
function1();
function2();
} else if (xhr.status === 400) {
function3();
function2();
} else if (xhr.status != 400 && xhr.status != 200) {
function5();
function6();
}
}
xhr.send(body);
})
根据您的代码、您的观察以及您在评论中提供的上下文,您有两个问题:
- 发送表单数据
- 评估响应
让我们假设一些像这样的基本形式:
<form action="endpoint.php" method="post">
<input type="hidden" name="token" value="value">
<input type="submit" name="submit" value="submit">
</form>
为了能够自己发送此表单的数据,我们需要确保我们拦截浏览器的默认行为,即在单击提交按钮后立即提交它(另请参阅 epascarello 的评论):
// 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)); //
sendRequest(data); // Our submit function, which we'll define next (see below)
};
现在,我们可以实际发送数据,并正确处理服务器发回的消息和状态代码。但首先,让我们快速浏览一下您的 if
子句,因为它们可能无法按您期望的方式工作。特别是因为 state 和 status 不是相互排斥的 - readyState
为 4 并不意味着服务器没有回答表示错误的 HTTP 状态代码(如 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)
}
因此,让我们以不同的方式处理该部分,而其余代码保持不变(尽管包含在一个函数中):
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);
}
现在,您应该能够成功发送表单数据(并将其作为 JSON 发送)并评估 HTTP 响应状态代码。不过,您可能不想使用 XMLHttpRequest
,而是考虑使用 fetch()
。
杂项:
我正在尝试 运行 基于我 xhr
的 readystate
的条件语句。 readystate
在 open()
被调用(第 2 行)后切换到 1
,但此后永远不会改变。它会跳过条件,并且不会发送任何内容。
我很想知道为什么 readystate
没有改变?
var xhr = new XMLHttpRequest();
xhr.open('POST', submitUrl, true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
function1();
function2();
} else if (xhr.status === 400) {
function3();
function2();
} else if (xhr.status != 400 && xhr.status != 200) {
function5();
function6();
}
}
xhr.send(body);
})
根据您的代码、您的观察以及您在评论中提供的上下文,您有两个问题:
- 发送表单数据
- 评估响应
让我们假设一些像这样的基本形式:
<form action="endpoint.php" method="post">
<input type="hidden" name="token" value="value">
<input type="submit" name="submit" value="submit">
</form>
为了能够自己发送此表单的数据,我们需要确保我们拦截浏览器的默认行为,即在单击提交按钮后立即提交它(另请参阅 epascarello 的评论):
// 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)); //
sendRequest(data); // Our submit function, which we'll define next (see below)
};
现在,我们可以实际发送数据,并正确处理服务器发回的消息和状态代码。但首先,让我们快速浏览一下您的 if
子句,因为它们可能无法按您期望的方式工作。特别是因为 state 和 status 不是相互排斥的 - readyState
为 4 并不意味着服务器没有回答表示错误的 HTTP 状态代码(如 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)
}
因此,让我们以不同的方式处理该部分,而其余代码保持不变(尽管包含在一个函数中):
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);
}
现在,您应该能够成功发送表单数据(并将其作为 JSON 发送)并评估 HTTP 响应状态代码。不过,您可能不想使用 XMLHttpRequest
,而是考虑使用 fetch()
。
杂项: