mode: 'no-cors'
волшебным образом не заставит все работать. На самом деле это только усугубляет ситуацию, потому что одним из следствий этого является указание браузерам: «Запретить моему внешнему JavaScript-коду просматривать содержимое тела и заголовков ответа при любых обстоятельствах». Конечно, вы почти никогда не хочу это.
Что происходит с запросами из разных источников из внешнего интерфейса JavaScript, так это то, что браузеры по умолчанию блокируют доступ кода внешнего интерфейса к ресурсам из разных источников. Если Access-Control-Allow-Origin
находится в ответе, браузеры ослабят эту блокировку и позволят вашему коду получить доступ к ответу.
Но если сайт не отправляет Access-Control-Allow-Origin
в своих ответах, ваш интерфейсный код не может напрямую получить доступ к ответам с этого сайта. В частности, вы не можете исправить это, указав mode: 'no-cors'
(фактически, это гарантирует, что ваш код внешнего интерфейса не сможет получить доступ к содержимому ответа).
Однако одна вещь, которая будет работать: если вы отправите свой запрос через прокси CORS.
Вы также можете легко развернуть собственный прокси на Heroku буквально за 2-3 минуты с помощью 5 команд:
git clone https://github.com/Rob--W/cors-anywhere.git
cd cors-anywhere/
npm install
heroku create
git push heroku master
После выполнения этих команд у вас будет собственный сервер CORS Anywhere, работающий, например, по адресу https://cryptic-headland-94862.herokuapp.com/
.
Префикс URL-адреса вашего запроса с URL-адресом вашего прокси-сервера; Например:
https://cryptic-headland-94862.herokuapp.com/https://example.com
Добавление URL-адреса прокси в качестве префикса приводит к тому, что запрос выполняется через ваш прокси, который затем:
- Перенаправляет запрос на
https://example.com
.
- Получает ответ от
https://example.com
.
- Добавляет заголовок
Access-Control-Allow-Origin
к ответу.
- Передает этот ответ с добавленным заголовком обратно запрашивающему коду внешнего интерфейса.
Затем браузер позволяет коду внешнего интерфейса получить доступ к ответу, потому что этот ответ с заголовком ответа Access-Control-Allow-Origin
- это то, что браузер видит.
Это работает, даже если это запрос, который заставляет браузеры выполнять предварительный OPTIONS
запрос CORS, потому что в этом случае прокси также отправляет обратно заголовки Access-Control-Allow-Headers
и Access-Control-Allow-Methods
, необходимые для успешной предварительной проверки.
Я могу попасть в эту конечную точку http://catfacts-api.appspot.com/api/facts?number=99
через Postman
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS объясняет, почему даже если вы можете получить доступ к ответу с помощью Postman, браузеры не позволят вам получить доступ к ответу из разных источников из внешнего кода JavaScript, запущенного в веб-приложении, если ответ не содержит Access-Control-Allow-Origin
заголовок ответа.
http://catfacts-api.appspot.com/api/facts?number=99 не имеет Access-Control-Allow-Origin
заголовка ответа, поэтому код внешнего интерфейса не может получить доступ к ответу из разных источников.
Ваш браузер может получить ответ нормально, и вы можете увидеть его в Postman и даже в инструментах разработчика браузера, но это не значит, что браузеры будут предоставлять его вашему коду. Не получат, потому что у него нет Access-Control-Allow-Origin
заголовка ответа. Поэтому вместо этого вы должны использовать прокси, чтобы получить его.
Прокси-сервер отправляет запрос на этот сайт, получает ответ, добавляет заголовок ответа Access-Control-Allow-Origin
и любые другие необходимые заголовки CORS, а затем передает его обратно в ваш запрашивающий код. И этот ответ с добавленным заголовком Access-Control-Allow-Origin
- это то, что видит браузер, поэтому браузер позволяет вашему коду внешнего интерфейса фактически получать доступ к ответу.
Итак, я пытаюсь передать объект в свой Fetch, который отключит CORS.
Ты не хочешь этого делать. Для ясности: когда вы говорите, что хотите «отключить CORS», кажется, вы на самом деле имеете в виду, что хотите отключить политика одного и того же происхождения. На самом деле CORS - это способ сделать это - CORS - это способ ослабить политику одного и того же происхождения, а не способ ее ограничить.
Но в любом случае это правда, что вы можете - только в своей локальной среде - делать такие вещи, как давать своему браузеру флаги времени выполнения, чтобы отключить безопасность и работать небезопасно, или вы можете установить расширение браузера локально, чтобы обойти политику одного и того же происхождения, но все, что делает это изменить ситуацию только для вас на месте.
Независимо от того, что вы изменяете локально, любой, кто пытается использовать ваше приложение, по-прежнему будет сталкиваться с политикой того же происхождения, и вы не можете отключить это для других пользователей вашего приложения.
Скорее всего, вы никогда не захотите использовать mode: 'no-cors'
на практике, за исключением нескольких ограниченных случаев, и даже тогда, только если вы точно знаете, что делаете и каковы эффекты. Это потому, что параметр mode: 'no-cors'
на самом деле говорит браузеру: «Запретить моему внешнему JavaScript-коду просматривать содержимое тела и заголовков ответа при любых обстоятельствах». В большинстве случаев это явно не то, что вам нужно. хотеть.
Что касается случаев, когда вы хотели бы рассмотреть возможность использования mode: 'no-cors'
, см. Ответ на странице Какие ограничения применяются к непрозрачным ответам? для получения подробной информации. Суть в том, что кейсы:
В ограниченном случае, когда вы используете JavaScript для помещения содержимого из другого источника в элемент <script>
, <link rel=stylesheet>
, <img>
, <video>
, <audio>
, <object>
, <embed>
или <iframe>
(который работает, потому что для них разрешено встраивание ресурсов из другого источника) - но по какой-то причине вы не хотите или не можете этого сделать, просто используя в разметке документа URL-адрес ресурса в качестве атрибута href
или src
для элемента.
Когда единственное, что вы хотите сделать с ресурсом, - это кэшировать его. Как указано в ответе Какие ограничения применяются к непрозрачным ответам?, на практике сценарий, который применяется, - это когда вы используете Service Workers, и в этом случае релевантным API является Cache Storage API.
Но даже в этих ограниченных случаях следует помнить о некоторых важных подводных камнях; см. ответ на странице Какие ограничения применяются к непрозрачным ответам? для получения подробной информации.
Я также пытался передать объект { mode: 'opaque'}
Режима запроса mode: 'opaque'
отсутствует - opaque
вместо этого является просто свойством ответа, и браузеры устанавливают это свойство непрозрачности для ответов на запросы, отправленные в режиме no-cors
.
Но, кстати, слово непрозрачный является довольно явным сигналом о природе ответа, который вы получите: «непрозрачный» означает, что вы его не видите.
person
sideshowbarker
schedule
07.04.2017