2016-11-14 1 views
3

Мне нужно сделать запрос HTTP GET с настраиваемыми заголовками запросов в браузере и обработать результат по мере его поступления. Fetch API идеально подходит для этого:Fetch API, пользовательские заголовки запросов, CORS и перекрестные переадресации

fetch('https://example.com/resource', { 
    method: 'GET', 
    headers: { 
    'X-Brad-Test': 'true' 
    }, 
    cache: 'no-store', 
    mode: 'cors' 
}).then((res) => { 
    const reader = res.body.getReader(); 
    // etc. 
}); 

Это работает довольно хорошо. Поскольку есть пользовательские заголовки, браузер предварительно отправляет запрос с запросом OPTIONS на /resource. Я настроил мой сервер реагировать с 204 No Content и следующими заголовками:

Access-Control-Allow-Headers: X-Requested-With, Range, If-Range, X-Brad-Test 
Access-Control-Allow-Origin: * 

Браузер доволен этим, то делает запрос GET, сервер возвращает 200 OK с данными, а браузер позволяет мне доступ к заголовкам ответов и телу.

Проблема возникает, когда есть перенаправление. Запрос OPTIONS выполняется с 204 No Content и теми же заголовками, что и раньше. Браузер делает правильный запрос GET, а на сервере я посылаю 302 с заголовком Location:. Хром выдает следующую ошибку:

Fetch API cannot load https://example.com/resource . Redirect from ' https://example.com/resource ' to ' http://some-other-origin/resource ' has been blocked by CORS policy: Request requires preflight, which is disallowed to follow cross-origin redirect.

Это неожиданно и кажется бессмысленным для меня. Я ожидал, что браузер последует за переадресацией и выполнит еще один предполетный запрос для этого нового местоположения, но он этого не сделал.

Незнакомка по-прежнему заключается в том, что я могу как-то взломать эту клиентскую сторону. Я могу сделать HTTP-запрос без моего настраиваемого заголовка, выяснить, где я закончил после перенаправления, посмотрев на объект Response, а затем сделайте второй запрос в новой цели с моими настраиваемыми заголовками. Конечно, это не работает во всех случаях, и я бы предпочел не полагаться на этот хак. Я бы предпочел найти правильный путь.

два вопроса:

  • Что такое правильный способ, чтобы позволить клиенту следовать переадресовывает? Есть ли какой-то заголовок Access-Control-*, который я могу использовать?
  • Почему это ограничение существует? Какую проблему безопасности можно предотвратить, не следуя и не выполняя предполетный рейс по следующему URL-адресу?
+0

Ваш ответ 302 включает в себя заголовок 'Access-Control-Allow-Origin: *'? – sideshowbarker

+1

OK Я смутно вспоминаю прошлое обсуждение этого вопроса и проведу некоторое время, оглядываясь назад на спецификацию, и поговорю с редактором и разработчиками, чтобы узнать, могу ли я заставить кого-нибудь опубликовать здесь ответ (или выложите его сам, если мне удастся получить это выяснилось на моем собственном первом). – sideshowbarker

+0

См. Также http://stackoverflow.com/questions/34949492/cors-request-with-preflight-and-redirect-disallowed-workarounds/39728229#39728229 и https://github.com/whatwg/fetch/issues/204 – sideshowbarker

ответ

5

Поддержка перенаправлений на запросы, требующие предполетного контроля, - это очень недавнее изменение в Fetch (которое определяет CORS).

https://github.com/whatwg/fetch/commit/0d9a4db8bc02251cc9e391543bb3c1322fb882f2

Я считаю, что некоторые реализации приступили к корректировке своих реализаций, но это займет некоторое время, чтобы дойти до каждого.

+1

Спасибо. Знаете ли вы аргументы в пользу этого ограничения в первую очередь? Это просто ошибка или кейс? Кроме того, есть ли какие-нибудь более эффективные способы решения, чем я предложил в вопросе? – Brad

+1

Мы не хотели в то время вычислять модель обработки, не понимая, что блокирование переадресаций было на самом деле более сложным.Это была ошибка, и потребовалось много времени, чтобы исправить, так как никто действительно не жаловался на это. (Не могу придумать лучшего обходного пути.) – Anne

+0

Есть ли какие-либо новые успехи в этом вопросе? –

Смежные вопросы