Chrome会在HTTP 302重定向时取消CORS XHR

时间:2013-08-30 18:33:25

标签: google-chrome redirect xmlhttprequest cors .net-internals

看起来根据CORS Spec,GET和POST请求应该透明地遵循302重定向。但Chrome正在取消我的请求。

这是执行请求的JS:

var r = new XMLHttpRequest();
r.open('GET', 'https://dev.mysite.com/rest', true);
r.send();

以下是应该发生的事情:

  1. 客户:XHR POST请求/ rest
  2. 服务器:使用HTTP 302重定向到/ rest /
  3. 进行响应
  4. 客户:遵循该重定向
  5. 但在第2步之后,Chrome会取消该请求。如果没有HTTP 302,请求将完美地运行。我已经证实了这一点。

    当请求运行时,我可以在Chrome的“网络”面板中看到只有一个XHR - 已取消的POST请求,没有响应标头或响应正文。

    使用Chrome的net-internals工具进行调试,我发现服务器发送了响应,之后请求被取消。以下是请求的输出:

    79295: URL_REQUEST
    https://dev.mysite.com/rest
    Start Time: 2013-08-30 12:41:11.637
    
    t=1377880871637 [st=    0] +REQUEST_ALIVE  [dt=13455]
    t=1377880871638 [st=    1]    URL_REQUEST_BLOCKED_ON_DELEGATE  [dt=1]
                                  --> delegate = "extension Adblock Plus"
    t=1377880871639 [st=    2]   +URL_REQUEST_START_JOB  [dt=13453]
                                  --> load_flags = 143540480 (DO_NOT_SAVE_COOKIES | DO_NOT_SEND_AUTH_DATA | DO_NOT_SEND_COOKIES | ENABLE_LOAD_TIMING | MAYBE_USER_GESTURE | REPORT_RAW_HEADERS | VERIFY_EV_CERT)
                                  --> method = "POST"
                                  --> priority = 2
                                  --> upload_id = "0"
                                  --> url = "https://dev.mysite.com/rest"
    t=1377880871639 [st=    2]      HTTP_CACHE_GET_BACKEND  [dt=0]
    t=1377880871639 [st=    2]     +HTTP_STREAM_REQUEST  [dt=7]
    t=1377880871646 [st=    9]        HTTP_STREAM_REQUEST_BOUND_TO_JOB
                                      --> source_dependency = 79296 (HTTP_STREAM_JOB)
    t=1377880871646 [st=    9]     -HTTP_STREAM_REQUEST
    t=1377880871646 [st=    9]     +HTTP_TRANSACTION_SEND_REQUEST  [dt=0]
    t=1377880871646 [st=    9]        HTTP_TRANSACTION_SEND_REQUEST_HEADERS
                                      --> GET /facultyportfolio-rest HTTP/1.1
                                          Host: dev.liberty.edu
                                          Connection: keep-alive
                                          Content-Length: 46
                                          Origin: http://localhost:8080
                                          User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.62 Safari/537.36
                                          Content-Type: application/json; charset=UTF-8
                                          Accept: */*
                                          Referer: http://localhost:8080/ajaxtest.html
                                          Accept-Encoding: gzip,deflate,sdch
                                          Accept-Language: en-US,en;q=0.8
    t=1377880871646 [st=    9]        HTTP_TRANSACTION_SEND_REQUEST_BODY
                                      --> did_merge = true
                                      --> is_chunked = false
                                      --> length = 46
    t=1377880871646 [st=    9]     -HTTP_TRANSACTION_SEND_REQUEST
    t=1377880871646 [st=    9]     +HTTP_TRANSACTION_READ_HEADERS  [dt=1001]
    t=1377880871646 [st=    9]        HTTP_STREAM_PARSER_READ_HEADERS  [dt=1000]
    t=1377880872646 [st= 1009]        HTTP_TRANSACTION_READ_RESPONSE_HEADERS
                                      --> HTTP/1.1 302 Found
                                          Date: Fri, 30 Aug 2013 16:41:11 GMT
                                          Server: Apache/2
                                          Access-Control-Allow-Origin: http://localhost:8080
                                          Access-Control-Allow-Credentials: true
                                          Location: https://dev.mysite.com/rest/
                                          Content-Language: en-US
                                          Vary: Accept-Encoding,User-Agent
                                          Content-Encoding: gzip
                                          Content-Length: 20
                                          Connection: close
                                          Content-Type: text/plain; charset=UTF-8
    t=1377880872647 [st= 1010]     -HTTP_TRANSACTION_READ_HEADERS
    t=1377880872647 [st= 1010]     +URL_REQUEST_BLOCKED_ON_DELEGATE  [dt=12445]
    t=1377880885091 [st=13454]        CANCELLED
    t=1377880885092 [st=13455]   -URL_REQUEST_START_JOB
                                  --> net_error = -3 (ERR_ABORTED)
    t=1377880885092 [st=13455] -REQUEST_ALIVE
    

    最后,由于“URL_REQUEST_BLOCKED_ON_DELEGATE”,您可以看到“已取消”。我不知道这意味着什么。但同样,如果没有HTTP 302重定向,则不会发生错误。

    有谁知道导致Chrome取消此请求的原因是什么?

4 个答案:

答案 0 :(得分:20)

这里的答案是混合的,暗示代码中的某些设置等可能解决了CORS的重定向问题,但CORS规范明确规定了此类CORS重定向何时失败/通过: 根据规范,浏览器应该

  1. 如果对重定向资源的请求不需要进行飞行前检查(例如,没有自定义标头的简单CORS请求),则允许3XX重定向。请参阅https://www.w3.org/TR/cors/#simple-cross-origin-request-0
  2.   

    如果未设置手动重定向标志且响应的HTTP状态代码为301,302,303,307或308   应用重定向步骤

    1. 如果重定向资源的请求需要进行飞行前检查,则不允许3XX重定向。请参阅https://www.w3.org/TR/cors/#cross-origin-request-with-preflight-0
    2.   

      如果响应的HTTP状态代码为301,302,303,307或308   应用缓存和网络错误步骤。

      我在github repo中探索了各种CORS场景:https://github.com/monmohan/cors-experiment

      此失败重定向的特定问题也可以通过此处的捆绑包单独复制:https://github.com/monmohan/cors-experiment/tree/master/issue

答案 1 :(得分:9)

http://httpstatus.es/302

  

如果收到302状态代码以响应GET或HEAD以外的请求,则除非用户可以确认,否则用户代理不得自动重定向请求,因为这可能会改变请求的条件。发出的。

答案 2 :(得分:9)

我发现这篇关于setting the correct Access-Control-Allow-Origin CORS header on your 302 response的帖子很有帮助,至少在我听起来类似的情况下。

  

调查问题表明他的XHR没有登陆   直接启用CORS的URL,但正被重定向到它   HTTP 302(重定向)响应。

     

请记住,重定向网址还必须包含   Access-Control-Allow-Origin标头,否则浏览器将停止正确   有尝试的跨域请求。

我还发现在Access-Control-Allow-Origin之上设置额外的CORS标头通常会导致取消事务。

答案 3 :(得分:2)

我还遇到了Chrome没有跟踪CORS请求重定向的问题。对我来说问题是我使用的JS框架(Sencha Touch)添加了一个请求标头:X-Requested-With:“XMLHttpRequest”

一旦我删除了它(在Sencha Touch中调用Ext.Ajax.setUseDefaultXhrHeader(false);)它就像一个魅力。

不确定原因,但我希望这些信息有助于某人。