edit 2018-09-13 : добавлены некоторые уточнения относительно этого запроса перед полетом и как его избежать в конце этого ответа.
OPTIONS
запросы - это то, что мы называем pre-flight
запросами Cross-origin resource sharing (CORS)
.
Они необходимы, когда вы делаете запросы из разных источников в определенных ситуациях.
Этот предполетный запрос сделан некоторыми браузерами как мера безопасности, чтобы гарантировать, что выполняемый запрос является доверенным сервером. Это означает, что сервер понимает, что метод, источник и заголовки, отправляемые по запросу, безопасны для действий.
Ваш сервер не должен игнорировать, а обрабатывать эти запросы всякий раз, когда вы пытаетесь выполнить запросы из разных источников.
Хороший ресурс можно найти здесь http://enable-cors.org/
Чтобы справиться с этим, чтобы убедиться, что для любого пути с OPTIONS
методом сервер отправляет ответ с этим заголовком
Access-Control-Allow-Origin: *
Это скажет браузеру, что сервер готов отвечать на запросы любого происхождения.
Для получения дополнительной информации о том, как добавить поддержку CORS на ваш сервер, смотрите следующую блок-схему
http://www.html5rocks.com/static/images/cors_server_flowchart.png
редактировать 2018-09-13
OPTIONS
Запрос CORS запускается только в некоторых случаях, как описано в документах MDN :
Некоторые запросы не запускают предварительную проверку CORS. В этой статье они называются «простыми запросами», хотя в спецификации Fetch (которая определяет CORS) этот термин не используется. Запрос, который не запускает предварительную проверку CORS - так называемый «простой запрос» - это запрос, который удовлетворяет всем следующим условиям:
Единственные допустимые методы:
Помимо заголовков, автоматически устанавливаемых пользовательским агентом (например, Connection, User-Agent или любым другим заголовком с именами, определенными в спецификации Fetch как «имя запрещенного заголовка»), единственными заголовками, которым разрешено быть вручную устанавливаются те, которые спецификация Fetch определяет как «заголовок запроса CORS-safelisted», а именно:
- принимать
- Accept-Language
- Content-Language
- Content-Type (но обратите внимание на дополнительные требования ниже)
- DPR
- Downlink
- Сохранить данные
- ВЭкран-Ширина
- ширина
Единственные допустимые значения для заголовка Content-Type:
- применение / х-WWW-форм-urlencoded
- многочастному / форм-данных,
- текст / обычный
Ни один прослушиватель событий не зарегистрирован ни в одном объекте XMLHttpRequestUpload, используемом в запросе; доступ к ним осуществляется с помощью свойства XMLHttpRequest.upload.
В запросе не используется объект ReadableStream.
curl
для API это работает, но при запуске из Chrome я получаю ошибку?Origin
заголовок к вашему запросу, чтобы имитировать, как если бы запрос исходил от определенного хоста (например, yourwebsite.com). Вы также можете смоделировать предварительные запросы, установив HTTP-метод запросаOPTIONS
иAccess-Control-*
заголовкиПрошел эту проблему, ниже мой вывод на эту проблему и мое решение.
Согласно стратегии CORS (настоятельно рекомендуем вам прочитать об этом) Вы не можете просто заставить браузер прекратить отправку запроса OPTIONS, если он сочтет это необходимым.
Есть два способа обойти это:
Access-Control-Max-Age
для запроса ОПЦИИПростой запрос
Простой межсайтовый запрос - это тот, который удовлетворяет всем следующим условиям:
Единственные допустимые методы:
Помимо заголовков, автоматически устанавливаемых пользовательским агентом (например, Connection, User-Agent и т. Д.), Единственными заголовками, которые разрешено устанавливать вручную, являются:
Единственные допустимые значения для заголовка Content-Type:
Простой запрос не вызовет предполетный запрос ОПЦИИ.
Установить кеш для проверки ОПЦИИ
Вы можете установить
Access-Control-Max-Age
для запроса OPTIONS, чтобы он не проверял разрешение снова, пока не истечет срок его действия.Ограничение отмечено
Access-Control-Max-Age
составляет600
10 минут, согласно исходному коду Chrome.Access-Control-Max-Age
работает только для одного ресурса каждый раз, например,GET
запросы с одинаковым URL-путем, но разные запросы будут рассматриваться как разные ресурсы. Таким образом, запрос ко второму ресурсу будет по-прежнему вызывать предварительный запрос.источник
Access-Control-Max-Age
. Это ключ здесь. Это поможет вам избежать чрезмерных предварительных запросов.application/json
только потому, что это делает ваш запрос не «простым» (и, следовательно, запускает CORS). Браузер делает свою работу. Настройте свой сервер так, чтобы он возвращал заголовок,Access-Control-Max-Age: 86400
и браузер не будет повторно отправлять запрос OPTIONS в течение 24 часов.Пожалуйста, направьте этот ответ на вопрос о фактической потребности в предварительном запросе ОПЦИИ: CORS - Какова мотивация введения предварительных запросов?
Чтобы отключить запрос OPTIONS, для ajax-запроса должны быть выполнены следующие условия:
application/x-www-form-urlencoded
,multipart/form-data
илиtext/plain
Ссылка: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
источник
application/xml
илиapplication/json
не являются "пользовательскими заголовками HTTP". Заголовок сам по себе будет,Content-Type
и вызов этого заголовка «обычай» будет ввести в заблуждение.Когда у вас открыта консоль отладки и
Disable Cache
включена опция, предварительные запросы будут отправляться всегда (т.е. перед каждым запросом). если вы не отключите кеш, предполетный запрос будет отправлен только один раз (на сервер)источник
Да, можно избежать запроса параметров. Запрос параметров - это предварительный запрос при отправке (публикации) любых данных в другой домен. Это проблема безопасности браузера. Но мы можем использовать другую технологию: транспортный слой iframe. Я настоятельно рекомендую вам забыть о любой конфигурации CORS и использовать готовое решение, и оно будет работать где угодно.
Посмотрите здесь: https://github.com/jpillora/xdomain
И рабочий пример: http://jpillora.com/xdomain/
источник
Для разработчика, который понимает причину его существования, но ему нужен доступ к API, который не обрабатывает вызовы OPTIONS без аутентификации, мне нужен временный ответ, чтобы я мог развиваться локально, пока владелец API не добавит надлежащую поддержку SPA CORS или я не получу прокси-API и работает.
Я обнаружил, что вы можете отключить CORS в Safari и Chrome на Mac.
Отключить ту же политику происхождения в Chrome
Chrome: выйдите из Chrome, откройте терминал и вставьте эту команду:
open /Applications/Google\ Chrome.app --args --disable-web-security --user-data-dir
Safari: отключение политики одного источника в Safari
источник
Как уже упоминалось в предыдущих сообщениях,
OPTIONS
запросы есть по причине. Если у вас есть проблема с большим временем отклика от вашего сервера (например, соединение за границей), вы также можете настроить браузер для кэширования предварительных запросов.Пусть ваш сервер ответит
Access-Control-Max-Age
заголовком, а для запросов, отправляемых в ту же конечную точку, предварительный запрос будет кэширован и больше не будет выполняться.источник
OPTIONS
запросы будут кэшироваться с этим заголовком, довольно непрозрачен во всей документации CORS, которую я прочитал.Я решил эту проблему, как.
Это только для развития. С этим я жду 9мс и 500мс, а не 8с и 500мс. Я могу сделать это, потому что производственное JS-приложение будет находиться на той же машине, что и производственное, поэтому не будет,
OPTIONS
но разработка - это моя локальная разработка.источник
Вы не можете, но вы можете избежать CORS, используя JSONP.
источник
Проведя полтора дня, пытаясь решить подобную проблему, я обнаружил, что это связано с IIS .
Мой проект Web API был настроен следующим образом:
У меня не было конкретных параметров конфигурации CORS в узле web.config> system.webServer, как я видел во многих постах
Нет конкретного кода CORS в global.asax или в контроллере в качестве декоратора
Проблема была в настройках пула приложений .
Режим управляемого конвейера был установлен на классический ( изменил его на интегрированный ), а Identity был установлен на Network Service ( изменил его на ApplicationPoolIdentity )
Изменение этих настроек (и обновление пула приложений) исправило это для меня.
источник
Что мне помогло, так это импортировать «github.com/gorilla/handlers», а затем использовать его следующим образом:
Как только я выполнил запрос POST Ajax и прикрепил к нему данные JSON, Chrome всегда добавлял заголовок Content-Type, которого не было в моей предыдущей конфигурации AllowedHeaders.
источник
Одно из решений, которое я использовал в прошлом, - скажем, ваш сайт находится на mydomain.com, и вам нужно сделать ajax-запрос к foreigndomain.com
Настройте перезапись IIS с вашего домена на чужой домен - например,
на вашем сайте mydomain.com - вы можете сделать тот же запрос о происхождении, и нет необходимости в запросе опций :)
источник
Это может быть решено в случае использования прокси, который перехватывает запрос и записывает соответствующие заголовки. В конкретном случае Varnish это будут правила:
}
источник
Возможно, есть решение (но я его не тестировал): вы можете использовать CSP (Content Security Policy), чтобы включить удаленный домен, и браузеры могут пропустить проверку запроса CORS OPTIONS.
Я, если найду время, протестирую и обновлю этот пост!
CSP: https://developer.mozilla.org/fr/docs/Web/HTTP/Headers/Content-Security-Policy
Спецификация CSP: https://www.w3.org/TR/CSP/
источник