Мне нужно сделать запрос 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-адресу?
Ваш ответ 302 включает в себя заголовок 'Access-Control-Allow-Origin: *'? – sideshowbarker
OK Я смутно вспоминаю прошлое обсуждение этого вопроса и проведу некоторое время, оглядываясь назад на спецификацию, и поговорю с редактором и разработчиками, чтобы узнать, могу ли я заставить кого-нибудь опубликовать здесь ответ (или выложите его сам, если мне удастся получить это выяснилось на моем собственном первом). – sideshowbarker
См. Также http://stackoverflow.com/questions/34949492/cors-request-with-preflight-and-redirect-disallowed-workarounds/39728229#39728229 и https://github.com/whatwg/fetch/issues/204 – sideshowbarker