为啥 XmlHttpRequest readyState = 2 on 200 HTTP 响应代码

Posted

技术标签:

【中文标题】为啥 XmlHttpRequest readyState = 2 on 200 HTTP 响应代码【英文标题】:Why XmlHttpRequest readyState = 2 on 200 HTTP response code为什么 XmlHttpRequest readyState = 2 on 200 HTTP 响应代码 【发布时间】:2014-12-12 17:37:17 【问题描述】:

所以我使用纯 javascript(没有 jquery)将文件发送到服务器。服务器脚本 php 最后返回状态码 200,但 javascript 正在准备就绪状态 == 2。

PHP 代码发回状态码 200:

header('X-PHP-Response-Code: 200', true, 200);
exit;

javascript 正在做的事情:

request.onreadystatechange = function() 
        if (request.readyState == 4) 
            var message;
            switch(request.status) 
                case '200':
                     message = "Data uploaded successfully.";
                break;

                case '406':
                    message = "Incorrect file format.  Please try again.";
                break;

                case '410':
                    message = "Unexpected error.  Please contact support.";
                break;

                default:
                break;
            
            status_message_container.innerhtml = message;
            submit_button.disabled = false;
        
        else 
            alert( "Unexpected error:  " + this.statusText + ".\nPlease try again");
        
    ;

    request.send(formData);

即使知道 HTTP 200 状态代码在前端正确返回(我得到“OK”)。 JS 脚本看到 readyState==2(即 else 块总是命中)

我的理解是200的服务器状态码应该给readyState == 4??

【问题讨论】:

【参考方案1】:

首先,onreadystate 不只是被解雇一次。它被触发了多次,你需要能够处理它。这些是您需要处理的代码:

0 未发送 - open() 尚未被调用 1 OPENED - send() 尚未被调用 2 HEADERS_RECEIVED - send() 已被调用,并且标题和状态可用 3 LOADING 下载; - responseText 保存部分数据 4 - 操作完成

您的代码正在点击 readyState == 2 上的 else 块(已收到标头)并假设它不是错误状态。

您的错误检查应该在request.readyState == 4 检查中。这样,请求就完成了,但也可能出现错误:

if (request.readyState == 4) 
    switch(request.status) 
        case '200':
            message = "Data uploaded successfully.";
        break;
        // Error handling here
        default: alert( "Unexpected error:  " + this.statusText + ".\nPlease try again"); break;
    

https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest

【讨论】:

我意识到onreadystate 多次点击 - 实际上随时 readyState 变化。具体来说,我想知道为什么当我发回 HTTP 200 时 readyState 不是 4?到时候操作不是完成了吗?如果不是,服务器脚本必须给出什么指标才能获得readyState == 4编辑:您的代码将失败,因为在 HTTP 状态 200 上 readyState == 2。 您的 readyState 最终可能确实命中了已完成的块。只是当它收到错误时,它会首先击中“错误”部分。当收到响应时,它应该总是收到一个done——它是否是一个错误是由它的响应代码定义的。更新了答案以更好地解释 我的代码不会失败。当返回 any 状态代码时,readyState 为 both 2(收到标头时) 4(已下载响应时)。

以上是关于为啥 XmlHttpRequest readyState = 2 on 200 HTTP 响应代码的主要内容,如果未能解决你的问题,请参考以下文章

XMLHttpRequest 中的 onload 是不是等于 readyState==4?

xhr.readyState就绪状态

xhr.readyState的就绪状态

XMLHttpRequest Level 2 事件:等价于 readyState

ajax中XMLHttpRequest对象中readyState与status的几种常见状态

XMLHttpRequest对象的readyState和status区别