从 XMLHttpRequest 检索响应负载元素

Retrieving response payload elements from XMLHttpRequest

我正在向具有以下功能的服务器发送一个 JSON 请求(一个应用程序 login 但请求的类型无关紧要):

function login() {
    var payload = {
    "api_key" : "", "cmd" : "login",
    "params" : {}
    }
    payload["params"]["username"] = document.getElementById("uname").value
    payload["params"]["password"] = document.getElementById("passwd").value

    var xhr = new XMLHttpRequest();
    xhr.open("POST", "http://localhost:4000/api", true);
    xhr.setRequestHeader("Content-type", "application/json");
    xhr.setRequestHeader("Accept", "application/json");

    xhr.onreadystatechange = function() {
        if (xhr.readyState == 4) {
            resp = JSON.parse(xhr.responseText);
            console.log("resp.status=" + resp.status);
            console.log("resp.[\"status\"]=" + resp["status"]);
        }
    }
    xhr.send(JSON.stringify(payload));
}

我实际上在 responseText 字段中得到了正确的答复。例如,如果凭据错误,我会得到

{
  "status": "ko", 
  "errors": [
    {
      "cmd": "login",
      "long": "Login error : 'user-20' has no access to the system",
      "short": "login_error"
    }
  ]
}

如果凭据没问题,我会得到

{
  "status": "ok",
  ... some additional data
}   

但是,我无法获取 status 字段:resp.statusresp["status"] 始终是 undefined。如果调用是在异步模式 (xhr.open("POST", "http://localhost:4000/api", false);) 下完成的,或者如果我没有 JSON.parse() 回复,即:resp = xhr.responseText;.

更新 - 2017.09.06

我终于找到了让它工作的方法,但我不太明白为什么会这样。我居然改了

resp = JSON.parse(xhr.responseText);

进入

resp = JSON.parse(JSON.parse(xhr.responseText));

为了解决这个问题,我打印了 typeof(xhr.responseText),这是一个 sting。实际上 typeof(JSON.parse(xhr.responseText)) 也是一个 string,这就是它没有像 status 这样的字段的原因。最终,解析 xhr.responseText 两次得到一个 object,我实际上可以从中检索我的数据。

如果有人知道发生了什么,我会很感兴趣...我不知道这是否相关,但是发送 JSON 的应用程序服务器是最新版本Elixir/Phoenix,即1.5/1.3和JSON encoding/decoding是有毒的。

这是因为您已将 resp 变量分配给 responseText

resp = JSON.parse(xhr.responseText);

获取响应码

respCode = xhr.status

或者如果您希望两者都在同一个 resp 变量中,您可以这样做

resp = {
    responseText: xhr.responseText,
    status: xhr.status
}

然后您可以使用 resp.responseTextresp.status

访问它们