Почему отправляется запрос параметров и можно ли его отключить?
Я создаю веб-api. Я обнаружил, что всякий раз, когда я использую Chrome для публикации, добираюсь до своего API, всегда есть запрос на опцию, отправленный до реального запроса, что довольно раздражает. В настоящее время я получаю сервер, чтобы игнорировать любые параметры запроса. Теперь мои вопросы: что хорошо отправить запрос на опцию, чтобы удвоить нагрузку на сервер? Есть ли способ полностью остановить браузер от отправки запросов параметров?
15 ответов:
изменить 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
CORS
OPTIONSзапрос запускается только в некоторые случаи, как объяснено в MDN docs:Some requests don’t trigger a CORS preflight. Those are called “simple requests” in this article, though the Fetch spec (which defines CORS) doesn’t use that term. A request that doesn’t trigger a CORS preflight—a so-called “simple request”—is one that meets all the following conditions: The only allowed methods are: - GET - HEAD - POST Apart from the headers set automatically by the user agent (for example, Connection, User-Agent, or any of the other headers with names defined in the Fetch spec as a “forbidden header name”), the only headers which are allowed to be manually set are those which the Fetch spec defines as being a “CORS-safelisted request-header”, which are: - Accept - Accept-Language - Content-Language - Content-Type (but note the additional requirements below) - DPR - Downlink - Save-Data - Viewport-Width - Width The only allowed values for the Content-Type header are: - application/x-www-form-urlencoded - multipart/form-data - text/plain No event listeners are registered on any XMLHttpRequestUpload object used in the request; these are accessed using the XMLHttpRequest.upload property. No ReadableStream object is used in the request.
пожалуйста, обратитесь к этому ответу на фактическую потребность в предварительном запросе опций:CORS - какова мотивация введения предполетных запросов?
чтобы отключить запрос опций, для запроса ajax должны быть выполнены следующие условия:
- запрос не устанавливает пользовательские заголовки HTTP, такие как "application/xml" или "application/json" и т. д.
- метод запроса должен быть одним из GET, HEAD или POST. Если сообщение, тип контента должен быть один из
application/x-www-form-urlencoded,multipart/form-dataилиtext/plainссылка: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
прошли через эту проблему, ниже мой вывод по этому вопросу и мое решение.
по словам стратегия CORS (настоятельно рекомендуем Вам прочитать об этом) вы не можете просто заставить браузер прекратить отправку запроса опции, если он считает, что это необходимо.
есть два способа обойти это
- убедитесь, что ваш запрос является "простой запрос"
- Set
Access-Control-Max-Ageдля запроса опциипростой запрос
простой межсайтовый запрос-это запрос, удовлетворяющий всем следующим условиям:
единственные разрешенные методы: - ПОЛУЧИТЬ - ГЛАВА - В должности
кроме заголовков, установленных автоматически агентом пользователя (например, соединение, User-Agent и т. д.), только заголовки, которые могут быть установлены вручную: - Принимать - Принять-Язык - Содержание-Язык - Content-Type
единственными допустимыми значениями для заголовка типа содержимого являются: - приложение / x-www-форма-urlencoded - multipart/данные формы - text / plain
простой запрос не вызовет запрос опции перед полетом.
установите кэш для опции check
Вы можете установить
Access-Control-Max-Ageдля запроса опции, чтобы он не проверял разрешение снова, пока оно не истечет.Access-Control-Max-Age дает значение в секундах как долго ответ на запрос перед полетом может быть кэширован без отправки другого запроса перед полетом.
Да, это возможно, чтобы избежать заказу вариантов. Запрос параметров-это предварительный запрос при отправке (отправке) любых данных в другой домен. Это проблема безопасности браузера. Но мы можем использовать и другую технологию: iframe transport layer. Я настоятельно рекомендую вам забыть о любой конфигурации CORS и использовать готовое решение, и оно будет работать в любом месте.
посмотреть здесь: https://github.com/jpillora/xdomain
и работать образец: http://jpillora.com/xdomain/
хорошего дня!
когда у вас есть открытая консоль отладки и
Disable Cacheопция включена, предполетные запросы всегда будут отправляться (т. е. перед каждым запросом). если вы не отключите кэш, запрос перед полетом будет отправлен только один раз (на сервер)
Как уже упоминалось в предыдущих сообщениях,
OPTIONSпросит есть. Если у вас есть проблема с большим временем отклика от вашего сервера (например, зарубежное соединение), вы также можете кэшировать в своем браузере предполетные запросы.пусть ваш сервер ответит с
Access-Control-Max-Ageзаголовок и для запросов, которые идут в ту же конечную точку, запрос перед полетом будет кэшироваться и больше не возникнет.
для разработчика, который понимает причину его существования, но должен получить доступ к API, который не обрабатывает вызовы опций без auth, мне нужен временный ответ, чтобы я мог развиваться локально, пока владелец API не добавит соответствующую поддержку SPA CORS или я не получу прокси-API и не запустится.
Я обнаружил, что вы можете отключить CORS в Safari и Chrome на Mac.
отключить ту же политику происхождения в Chrome
Chrome: выход из Chrome, откройте терминал и вставьте это команда:
open /Applications/Google\ Chrome.app --args --disable-web-security --user-data-dirSafari:отключение политики того же происхождения в Safari
Если вы хотите отключить политику одинакового происхождения в Safari (у меня есть 9.1.1), вам нужно только включить меню разработчика и выбрать "отключить ограничения перекрестного происхождения" из меню разработки.
Я решил эту проблему, как.
if($_SERVER['REQUEST_METHOD'] == 'OPTIONS' && ENV == 'devel') { header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Headers: X-Requested-With'); header("HTTP/1.1 200 OK"); die(); }это только для развития. С этим я жду 9 мс и 500 мс, а не 8С и 500 мс. я могу это сделать, потому что производство JS приложение будет на той же машине, что и производство, так что не будет
OPTIONSно развитие мое локальное.
проведя целый день с половиной, пытаясь решить подобную проблему, я обнаружил, что это связано с IIS.
мой проект Web API был настроен следующим образом:
// WebApiConfig.cs public static void Register(HttpConfiguration config) { var cors = new EnableCorsAttribute("*", "*", "*"); config.EnableCors(cors); //... }у меня не было конкретных параметров конфигурации CORS в интернете.конфигурация > система.узел веб-сервера, как я видел во многих сообщениях
в глобальном коде нет кода CORS.asax или в контроллере в качестве декоратора
проблема было то настройки пула приложений.
на режим управляемого конвейера было установлено значение classic (изменил его на интегрированный) и личность был установлен в сетевую службу (изменил его на ApplicationPoolIdentity)
изменение этих настроек (и обновление пула приложений) исправило это для меня.
то, что сработало для меня, было импортировать "github.com/gorilla/handlers-а потом используй его так:
router := mux.NewRouter() router.HandleFunc("/config", getConfig).Methods("GET") router.HandleFunc("/config/emcServer", createEmcServers).Methods("POST") headersOk := handlers.AllowedHeaders([]string{"X-Requested-With", "Content-Type"}) originsOk := handlers.AllowedOrigins([]string{"*"}) methodsOk := handlers.AllowedMethods([]string{"GET", "HEAD", "POST", "PUT", "OPTIONS"}) log.Fatal(http.ListenAndServe(":" + webServicePort, handlers.CORS(originsOk, headersOk, methodsOk)(router)))Как только я выполнил запрос Ajax POST и прикрепил к нему данные JSON, Chrome всегда добавлял заголовок Content-Type, которого не было в моей предыдущей конфигурации AllowedHeaders.
Я думаю, вы отправляете запрос домен крест.
на кросс-домен запросы, установка типа контента на что-либо другое чем application / x-www-form-urlencoded,multipart / form-data, или text / plain вызовет браузер, чтобы отправить параметры предполетного запрос к серверу.
поэтому вам может потребоваться указать contentType to во избежание запросу вариант.
Пример Jquery: -
$.ajax({ url: "http://crossdomainurl", type: "POST", contentType: 'text/plain' });
возможно, есть решение (но я его не тестировал) : вы можете использовать CSP (политику безопасности контента), чтобы включить удаленный домен, и браузеры, возможно, пропустят проверку запроса параметров CORS.
Я если найду время, я проверю это и обновлю этот пост !
CSP : https://developer.mozilla.org/fr/docs/Web/HTTP/Headers/Content-Security-Policy
спецификация CSP:https://www.w3.org/TR/CSP/
одно решение, которое я использовал в прошлом-допустим, ваш сайт включен mydomain.com, и вам нужно сделать запрос ajax, чтобы foreigndomain.com
настройка перезаписи IIS из вашего домена во внешний домен-например
<rewrite> <rules> <rule name="ForeignRewrite" stopProcessing="true"> <match url="^api/v1/(.*)$" /> <action type="Rewrite" url="https://foreigndomain.com/{R:1}" /> </rule> </rules> </rewrite>на вашем mydomain.com сайт-вы можете сделать тот же запрос происхождения, и нет необходимости в каких-либо вариантах запроса :)
Это можно решить в случае использования прокси, которые перехватывают запрос и пишут соответствующие заголовки. В частном случае лака это были бы правила:
if (req.http.host == "CUSTOM_URL" ) { set resp.http.Access-Control-Allow-Origin = "*"; if (req.method == "OPTIONS") { set resp.http.Access-Control-Max-Age = "1728000"; set resp.http.Access-Control-Allow-Methods = "GET, POST, PUT, DELETE, PATCH, OPTIONS"; set resp.http.Access-Control-Allow-Headers = "Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,Keep-Alive,X-Requested-With,If-Modified-Since"; set resp.http.Content-Length = "0"; set resp.http.Content-Type = "text/plain charset=UTF-8"; set resp.status = 204; }}

Comments