【问题标题】:ajax error handling works not as expected with CORSajax 错误处理与 CORS 的预期不同
【发布时间】:2016-02-08 18:17:36
【问题描述】:

我还有一个关于 CORS 的问题。我为 ajax 设置了一些错误来处理一些错误,但问题是现在有些问题从未被跨域请求触发。

我知道不可能捕获预检(超时),因为它们是由浏览器触发的,是吗?但我认为应该可以使用 .e.g. 捕获内部服务器错误。获取之后。没有 CORS 的错误处理工作(原来 500 被转换为 0)

我从未调用过的设置:

jQuery.ajaxSetup({
        statusCode: {

            500: function (data, textStatus, jqxhr) {

                if (data.status === 500) {
                    window.location.hash = "#error";
                }
            }
        }
    });

GET 请求:

    jQuery.ajax({
        url: url,
        type:'GET',
        timeout:1000
    }).done (function (data, textStatus, jqXHR) {
        updateCookie (jqXHR);
        Logger.log("finished loading " + log);
        callback(data);

    }).fail (function (data, textStatus, jqXHR) {
        Logger.log("failure loading " + log);

    });

有人提示我如何解决这个问题吗? 问候

更新:ok再次调试,发现调用fail反而返回0f 500 -> status 0。


预检成功后的GET请求:

Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:44.0) Gecko/20100101 Firefox/44.0
Accept: */*
Accept-Language: de,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
X-CSRF-TOKEN: 11258a06-36ea-4a21-a935-d215fcc92714
X-Requested-With: undefined
Origin: null
Connection: keep-alive

在尝试获取已删除的资源时,服务器的响应符合预期:

Connection: close
Content-Language: en
Content-Type: text/html;charset=utf-8
Date: Mon, 08 Feb 2016 20:33:12 GMT
Server: Apache-Coyote/1.1
Transfer-Encoding: chunked
statusCode: 500

而不是这个 500 处于 ajax 设置状态 0 调用。

【问题讨论】:

  • 您想接收GET 请求吗?如果由于 CORS 收到 403 禁止,则没有以下 GET 请求。
  • 感谢您的回答。问题就像我在更新中所写的那样,我尝试捕获的一些错误与控制台中的不同。 500 为 0,例如从不调用超时(这可能是浏览器发送的预检问题,但我认为无法捕获它们)。 CORS 工作正常,但我也希望有一个良好的错误处理。反正有没有赶上预检的超时?为什么 500 使用 CORS 返回为 0 而不是没有?提前致谢
  • 哦,我认为我现在明白了:您的 preflight 请求得到了 500 响应。是对的吗?如果您的预检因任何原因失败,那么您的请求就会失败,并且您无法访问任何跨域信息。
  • 不完全是:例如,如果我请求一个不存在的源 -> 预检通过但 GET 返回 500 就可以了。但我想知道为什么从未抛出错误。原来 500 在 ajax 状态下是 0。但500并不是唯一的。不知道为什么。第二:如果预检超时,因为服务器没有响应我没有收到超时。但我相信不可能抓到它们,因为它们是由浏览器发送的,对吧?
  • (#1) 如果预检已经通过,并且您的 GET 已发出,那么您应该能够看到对您的 GET 的错误响应。您看到一个失败的 CORS 请求(在 成功 预检之后!)这一事实向我表明,您的 GET 响应有问题(例如,它缺少 Access-Control-Allow-Origin 或类似的东西会导致未预检的 CORS 请求失败)。 (#2) 无法从浏览器脚本中了解有关预检成功/失败的任何信息。

标签: ajax cors


【解决方案1】:

CORS 规范在 Cross-Origin Request with Preflight 部分下声明:

在发出预检请求时要遵守以下请求规则:

...

如果响应的 HTTP 状态码不在 2xx 范围内

  • 应用网络错误步骤。

如果出现网络错误

  • 如果出现 DNS 错误、TLS 协商失败或其他类型的网络错误,请应用网络错误步骤。不要请求任何类型的最终用户交互。

因此,满足 500 响应或遇到超时(或任何其他网络故障)的预检会触发规范的“网络错误步骤”。 network error steps 与出现一般 CORS 故障时使用的错误步骤相同(例如,允许错误的来源、根本不存在 CORS 标头等):

每当应用网络错误步骤时,终止调用这组步骤的算法并将跨域请求状态设置为网络错误

在浏览器环境中,“网络错误”状态对应状态0

为了防止这种情况发生,服务器必须确保预检不会失败。或者,更改您的请求,使其简单(即仅使用简单的方法和标头),因此不需要预检。

【讨论】:

  • 感谢您的回答。我明白了,所以当服务器没有运行并且预检没有通过时,总是抛出 0 状态?
  • @coffeLord 正确。离线服务器会导致网络故障。看到 500 响应的预检和由于离线服务器而失败的预检的客户端行为是相同的。
  • 好的,谢谢,再提一个问题或批准。如果我的预检通过并且我的 GET 收到 500,它也是状态 0?所以我必须明确抛出一个不同于 500 的错误来区分它们?
  • @coffeLord 如果您的预检通过,那么 GET 的实际响应状态代码将可见(即,您可以看到 500 响应)。如果您看不到 500 响应,则表示 您的请求中的 CORS 出现问题,无论是在预检中还是在实际请求中。既然您说预检正常,那么服务器一定不能为 GET 响应包含正确的 CORS 标头。成功预检后的实际响应被视为正常的 CORS 请求:它仍然需要 Access-Control-Allow-Origin
  • 我可以看到 500 响应,但在 ajax 错误处理中触发了 0 状态。这只发生在 CORS 上,没有触发 500。这是我不明白的
猜你喜欢
  • 2014-04-01
  • 2016-03-30
  • 1970-01-01
  • 2017-12-24
  • 2013-12-28
  • 1970-01-01
  • 2017-04-09
  • 1970-01-01
  • 2013-06-26
相关资源
最近更新 更多