Запрос CORS с предполетью и перенаправление: запрещено. Обходные?
Я разрабатываю API, который позволяет пользователю аутентифицироваться (используя токены) и который содержит перенаправления в пределах одного домена. Теперь, для неавторизованного запроса к конечной точке, которая возвращает 303,
GET /documents/123 --> 303 redirect to `/documents/abc`
GET /documents/abc --> 200
все работает хорошо.
Проделайте аутентифицированный запрос к той же конечной точке, где отправляется заголовок Authorization
. Это делает запрос предполетным запросом, и браузер выполняет предпросмотр OPTIONS
, т.е.
OPTIONS /documents/123 --> 204 (everything okay, please proceed)
GET /documents/123 --> 303 redirect to `/documents/abc`
В этот момент вместо GET
ting фактического ресурса в /documents/abc
браузер дает
XMLHttpRequest cannot load http://localhost:8000/people/username/nschloe.
The request was redirected to 'http://localhost:8000/people/YDHa-B2FhMie',
which is disallowed for cross-origin requests that require preflight.
Это соответствует стандарту:
7.1.5 Запрос на перекрестный запрос с предполетью
Если ответ имеет код состояния HTTP, который не находится в диапазоне 2xx
Примените шаги сетевой ошибки.
Это, по-видимому, означает, что нельзя перенаправлять для аутентифицированных ресурсов, даже если перенаправление находится в одном домене (localhost
).
Неужели это правда? Существует ли общее обходное решение?
Ответы
Ответ 1
Исходный стандарт исключает перенаправление после успешного предвыбора CORS. Цитата из раздела 7.1.5.3:
Это фактический запрос. Примените шаги make request и соблюдайте правила запроса ниже при оформлении запроса.
- Если в ответе есть код состояния HTTP из 301, 302, 303, 307 или 308 Примените шаги кэширования и сетевой ошибки.
Благодаря вашим усилиям (спасибо!), 4 августа стандарт был обновлен, чтобы разрешить перенаправление после успешной проверки предполета CORS.
До тех пор, пока браузеры не дойдут до конца, единственными возможными параметрами, по-видимому, являются одна или комбинация:
- Проблема перенаправляется только на простые запросы.
- Выпустите 305 redirect с собственным URL-адресом в заголовке
Location
в качестве "прокси". Будьте готовы к ограниченной поддержке браузера, поскольку 305 устарел.
- Сделайте поддельную "переадресацию":
- вернуть HTML с
meta refresh
и/или изменить Javascript Location
.
- вернуть HTML, который имеет заполнение виджета
iframe
с целью перенаправления в качестве источника iframe.
- отобразить ссылку, которую пользователь должен щелкнуть, чтобы получить доступ к контенту.