Подтвердить что ты не робот

Chrome отменяет CORS XHR при перенаправлении HTTP 302

Похоже, что согласно CORS Spec, запросы GET и POST должны прозрачно следовать 302 переадресациям. Но Chrome отменил мой запрос.

Здесь JS, который выполняет запрос:

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

Вот что должно получиться:

  • Клиент: запрос XHR POST для/отдыха
  • Сервер: отвечает на перенаправление HTTP 302 на /rest/
  • Клиент: выполните перенаправление

Но после шага 2 Chrome отменяет запрос. Если HTTP 302 не был, запрос будет работать отлично. Я подтвердил это.

Когда запрос выполняется, я вижу на панели Chrome Network только один XHR - отмененный запрос POST без заголовков ответа или тела ответа.

Отладка с помощью инструмента net-interns от Chrome, я вижу, что был отправлен ответ с сервера, после чего запрос был отменен. Вот результат запроса:

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 отменить этот запрос?

4b9b3361

Ответ 1

Ответы здесь неоднозначны, намекая на определенные настройки кода и т.д., которые могут решить проблему перенаправления с помощью CORS, но спецификация CORS четко указывает, когда такие переадресации CORS будут терпеть неудачу/пройти: Согласно спецификации, браузеры должны

  • Разрешает перенаправление 3XX, если запрос перенаправленного ресурса не требует предварительной проверки (простые запросы CORS без специального заголовка, например). См. https://www.w3.org/TR/cors/#simple-cross-origin-request-0

Если флаг перенаправления вручную отключен, а ответ имеет код состояния HTTP из 301, 302, 303, 307 или 308 Примените шаги перенаправления

  1. Не разрешать перенаправление 3XX, если запрос перенаправленного ресурса требует предварительной проверки. См. https://www.w3.org/TR/cors/#cross-origin-request-with-preflight-0

Если ответ имеет код состояния HTTP 301, 302, 303, 307 или 308 Примените шаги кэширования и сетевой ошибки.

Я изучил различные сценарии CORS в репозитории github: https://github.com/monmohan/cors-experiment.

Эта конкретная проблема с неудачной переадресацией также может быть легко воспроизведена изолированно с помощью пакета: https://github.com/monmohan/cors-experiment/tree/master/issue

Ответ 2

http://httpstatus.es/302

Если код статуса 302 получен в ответ на запрос, отличный от GET или HEAD, пользовательский агент НЕ ДОЛЖЕН автоматически перенаправлять запрос, если он не может быть подтвержден пользователем, поскольку это может изменить условия, при которых запрос был выдан.

Ответ 3

Я нашел этот пост о настройке правильного заголовка CORS для контроля доступа-Разрешить-Происхождение вашего ответа 302, чтобы быть полезным, по крайней мере, в мой похожий звук.

Исследование проблемы показало, что его XHR не приземлялся на напрямую связанный с CORS URL, но был перенаправлен на него через ответ HTTP 302 (перенаправление).

Поэтому имейте в виду, что URL перенаправления должен также включать Access-Control-Allow-Origin, иначе браузер перестанет работать там с его попыткой междоменного запроса.

Я также обнаружил, что установка дополнительных заголовков CORS выше и выше Access-Control-Allow-Origin часто приводит к отмене транзакции.

Ответ 4

У меня также возникла проблема, когда Chrome не выполнял перенаправление по запросу CORS. Для меня проблема заключалась в том, что используемая JS-инфраструктура (Sencha Touch) добавляет заголовок запроса: X-Requested-With: "XMLHttpRequest"

Как только я удалил это (в Sencha Touch, вызвав Ext.Ajax.setUseDefaultXhrHeader(false);), он работал как шарм.

Не знаю, почему, но я надеюсь, что эта информация поможет кому-то.