【问题标题】:XMLHTTPRequest keeps looping through conditional statements?XMLHTTPRequest 不断循环通过条件语句?
【发布时间】:2021-07-18 02:33:37
【问题描述】:

我正在尝试根据我的xhrreadystate 运行条件语句。 readystate 在调用 open() 后切换到 1(第 2 行),但此后不再更改。它跳过了条件,没有发送任何内容。

我很想知道为什么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);
})

【问题讨论】:

  • 如果在第一个if语句之前添加console.log(xhr.readyState);,那么控制台会说什么?
  • 您应该检查 readyState 4 的所有状态...。这段代码是如何调用的?
  • @epascarello -- 它被称为 onSubmit,它将输入传递给 PHP 函数 (submitUrl)。
  • 是表单提交吗?
  • 是的@epascarello

标签: javascript php xml xmlhttprequest


【解决方案1】:

根据您的代码、您的观察以及您在 cmets 中提供的上下文,您有两个问题:

  • 发送表单数据
  • 评估响应

让我们假设一些像这样的基本形式:

<form action="endpoint.php" method="post">
    <input type="hidden" name="token"  value="value">
    <input type="submit" name="submit" value="submit">
</form>

为了能够自己发送此表单的数据,我们需要确保拦截浏览器的默认行为,即在单击提交按钮后立即提交(参见 epascarello 的 cmets):

// 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)
};

现在,我们可以实际发送数据,并正确处理服务器发回的消息和状态代码。但首先,让我们快速浏览一下您的 if 子句,因为它们可能无法按您期望的方式工作。特别是因为 statestatus 不是互斥的 - 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 响应状态代码。不过,您可能需要考虑使用fetch(),而不是使用XMLHttpRequest

杂项:

【讨论】:

    猜你喜欢
    • 2019-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-13
    • 2013-12-29
    • 1970-01-01
    • 2020-11-21
    相关资源
    最近更新 更多