【问题标题】:How do I get the HTTP status code for a failed CORS request in jQuery?如何在 jQuery 中获取失败的 CORS 请求的 HTTP 状态代码?
【发布时间】:2020-07-18 11:57:07
【问题描述】:

我正在使用 jQuery 的 $.ajax 方法发送请求,并希望在请求未成功时打印 HTTP 状态代码。

当 POST/GET 请求本身因错误而失败时,一切都很好,并且可以在 error 回调中轻松打印错误。 但是,当浏览器发送预检 OPTIONS 请求并且失败(例如,由于 URL 错误而导致 404)时,回调不会打印任何有用的信息。

对于下面的示例,控制台会打印以下内容:

response: [object Object]
response.status: 0
response.statusText: error
response.responseText: undefined
status: error
error: 

当我在浏览器调试器中检查网络请求时,会收到以下响应头:

HTTP/1.0 404 NOT FOUND
Content-Type: application/json
Content-Length: 130
Access-Control-Allow-Origin: http://localhost:3000
Access-Control-Allow-Headers: content-type
Access-Control-Allow-Methods: DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT
Vary: Origin
Server: Werkzeug/1.0.0 Python/3.6.9
Date: Mon, 06 Apr 2020 13:01:47 GMT

如何获取 404 状态代码以打印有用的错误消息?目前,我唯一能做的就是打印unknown error,这并不能说明问题实际上是404。

示例代码:

import $ from 'jquery';

$(function() {
  $('#file-upload').on('change', function(e) {
    e.preventDefault();

    const files = $(this).prop('files');
    const file = files && files.length && files[0];

    const reader = new FileReader();
    reader.onload = (e) => {
      let encoded = e && e.target && e.target.result.toString().replace(/^data:(.*,)?/, '');

      $.ajax({
        type: 'POST',
        url: 'http://localhost:8000/upload',
        data: JSON.stringify({data: encoded}),
        contentType: 'application/json',
        dataType: 'json',
        cache: false,
        crossDomain: true,
        processData: true,

        success: (response) => {
          console.log('success');
        },

        error: (response, status, error) => {
          console.log("response: " + response);
          console.log("response.status: " + response.status);
          console.log("response.statusText: " + response.statusText);
          console.log("response.responseText: " + response.responseText);
          console.log("status: " + status);
          console.log("error: " + error);
        },

        complete: () => {
          $(this).val('');
        },
      });
    };

    if (file) {
      reader.readAsDataURL(file);
    }
  });

});

【问题讨论】:

  • 它不是同一个端口(@98​​7654327@ vs. 3000)所以它不应该工作
  • 我不明白,后端在 8000 上运行,前端在 3000 上运行。当后端从 GET 请求本身返回错误时,而不是从 OPTIONS 请求返回,一切正常。
  • 发生 CORS 错误时,您无法访问响应。这是出于安全原因而设计的。如果您在这种情况下同时拥有客户端和服务器,只需将 CORS 标头添加到您发送的响应中
  • 我同时拥有客户端和服务器,并且我确实设置了正确的 CORS 标头。但是,浏览器似乎向 /foo/bar 发送了一个 OPTIONS 请求,该请求可能不存在。因此,404 会使用正确的 CORS 标头发送。但是,客户端应用程序无法读取 404,因为浏览器显然将此视为 CORS 故障,尽管事实并非如此。
  • 您无法从前端代码访问 CORS 预检 OPTIONS 响应标头。浏览器不会向您的代码公开该 OPTIONS 响应。如果对预检 OPTIONS 请求的响应不是 200、204 或其他 2xx 成功代码,则预检失败并且浏览器会停在那里。因此,如果您的代码导致浏览器向 URL 发送预检请求,从而使服务器以 404 响应,那么您的其余代码将永远不会被执行——并且您的前端代码无法访问该 OPTIONS 响应的状态代码, 也不是它的响应头

标签: jquery cors


【解决方案1】:

问题确实是我的服务器以404 响应OPTIONS 请求。这使得浏览器将 CORS 请求解释为失败,因此不会传播任何状态代码。

为了解决这个问题,我修改了服务器以始终以 200 响应 CORS OPTIONS 请求。这使得请求成功,浏览器将执行以下 GET/POST 请求,然后失败并返回 404 并返回正确的失败,并正确传递到前端。

【讨论】:

    猜你喜欢
    • 2018-05-04
    • 1970-01-01
    • 1970-01-01
    • 2014-10-19
    • 1970-01-01
    • 1970-01-01
    • 2019-07-22
    • 2017-06-27
    • 2021-03-29
    相关资源
    最近更新 更多