IIS угоняет запрос CORS Preflight OPTIONS
Я делаю запрос CORS POST и устанавливаю заголовок Content-Type для json. Это запускает запрос Preflight OPTIONS для запуска (это хорошо и ожидаемо)
На этот запрос OPTIONS отвечает 200 OK, но это не из моего приложения WebAPI.
У меня есть собственный обработчик сообщений, и он так и не получил ответ, поэтому IIS отвечает на запрос до появления ASP.NET.
Я нашел несколько сообщений на эту тему, и они говорят следующее
Убедитесь, что WebDav удален / удален / отключен - ГОТОВО
Убедитесь, что OPTIONSVerbHandler удален / изменен для использования aspnet_isapi.dll - ОБЫЧНАЯ ОБА
Убедитесь, что extensionLURLHandler включает глагол OPTIONS - DONE
Тем не менее, мой запрос вариантов все еще получает угон. Я имею в виду, что IIS отвечает с 200 OK, но не включает в ответ заголовок Access-Control-Allow-Origin. Он не включает этот заголовок, потому что он никогда не попадает в мой код WebAPI CORS, который бы устанавливал этот заголовок.
Два лучших сообщения, которые я мог найти, которые звучат как моя проблема:
здесь: JQuery застрял на предполетной проверке CORS и призрачном ответе IIS
и здесь: http://brockallen.com/2012/10/18/cors-iis-and-webdav/
Я попытался включить отслеживание Failed Request (FERB) в IIS и настроить его на отслеживание всех 200 кодов состояния. Я никогда не вижу, чтобы запрос опций регистрировался... Не уверен, означает ли это, что FERB не отслеживает запросы OPTIONS или мне нужно что-то изменить в настройках FERB, чтобы он отслеживал запросы OPTIONS, или если это подсказка в чем моя проблема?
Это ASP.NET WebAPI 2.0, работающий на IIS 7.5 (также протестирован на IIS 8 и IISExpress с одинаковыми результатами). Не имеет значения, какой браузер (Chrome, FF и IE все не работают одинаково)
Я перепробовал все, что смог найти по этому вопросу, и до сих пор не могу решить свою проблему.
Помоги мне, Stackru, ты моя единственная надежда.
16 ответов
Несколько вещей, которые вы можете попробовать здесь, все связанные с web.config, сначала измените элемент вашего модуля, чтобы включить атрибут runAllManagedModulesForAllRequests="true"
, как показано ниже:
<modules runAllManagedModulesForAllRequests="true">
<remove name="WebDavModule" />
</modules>
Затем установите ваши обработчики ниже:
<handlers>
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />
<remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="WebDav" />
<remove name="OPTIONSVerbHandler" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
Это должно сработать, но если этого не произойдет, в качестве последнего средства вы можете заставить IIS вывести правильные заголовки с помощью приведенного ниже:
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="GET,PUT,POST,DELETE,OPTIONS" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
</customHeaders>
</httpProtocol>
</system.webServer>
Будьте осторожны с подстановочными знаками, вы должны установить это имя домена, на котором будет размещаться ваш сайт.
Вот что сработало у меня после 4 часов поисков / экспериментов:
<handlers>
<remove name="OPTIONSVerbHandler" />
<add name="OPTIONSVerbHandler" path="*" verb="OPTIONS" modules="IsapiModule" scriptProcessor="C:\Windows\System32\inetsrv\asp.dll" resourceType="Unspecified" requireAccess="None" />
</handlers>
Я испробовал все вышеупомянутые предложения, а также другие, которые я нашел в SO, и в моей ситуации имело значение то, что у нас была включена фильтрация запросов в IIS, а глагол OPTIONS HTTP не был в списке разрешенных глаголов. Как только я добавил это, я был в состоянии разобраться с остальным.
У меня была та же проблема, и следующие настройки web.config устранили ее для меня.
<modules runAllManagedModulesForAllRequests="false">
<remove name="FormsAuthenticationModule" />
</modules>
<handlers>
<remove name="OPTIONSVerbHandler" />
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
Затем я смог обработать запросы CORS OPTIONS вручную в Application_BeginRequest.
Первоначально я использовал библиотеку, подробно описанную в этом блоге, для обработки запросов CORS. Продукт, над которым я работаю, требует, чтобы для runAllManagedModulesForAllRequests было установлено значение false. Вот почему я должен был настроить пользовательскую реализацию, но если у вас нет этого требования, вы должны попробовать эту библиотеку. Это прекрасно работало, когда я смог установить для runAllManagedModulesForAllRequests значение true.
В нашем случае это была фильтрация запросов в IIS, отключающая глагол OPTIONS на уровне корневого веб-приложения. Откройте диспетчер IIS, щелкните корневое приложение, щелкните "Фильтрация запросов", если в списке появится "OPTIONS", "Удалить" или "Разрешить глагол". Жаль, что я проверил это первым, как много потерянного времени.
Вот что сработало для меня:
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
Проверьте, установлен ли инструмент URLScan в IIS. В таком случае проверьте следующий раздел:
;
; The verbs (aka HTTP methods) listed here are those commonly
; processed by a typical IIS server.
;
; Note that these entries are effective if "UseAllowVerbs=1"
; is set in the [Options] section above.
;
GET
HEAD
POST
OPTIONS
В моем случае я пропустил пакет Microsoft.WebApi.Cors. Установил этот пакет и настроил его так в классе WebApiConfig:
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.EnableCors(new EnableCorsAttribute("*","*","*"));
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
Пожалуйста, отрегулируйте это перед использованием в производстве, потому что вы, вероятно, не хотите использовать подстановочные знаки для всего
Еще один случай, может быть, это сэкономит кому-то время. Когда я использовал конфигурацию с HttpConfiguration.EnableCors, все работало нормально, но когда я использовал файл web.config , он терпел неудачу с ошибками CORS. Он начал работать после того, как я удалил папку .vs .
Я перепробовал все упомянутые посты, но у меня ничего не получалось, затем я переместил свой сервис ASP.Net Web API 2 на Windows Server 2012 (IIS 8.5), и тот же сервис работал без каких-либо изменений. Так что проблема была специфична для IIS 7.5 на Windows 7 машина.
Я установил Microsoft.AspNet.WebApi.Cors
& Microsoft.Owin.Cors
для моего oWin на основе WebAPI и добавил app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
в конфигурации, как показано ниже:
public class Startup : IStartup, IAppStartup
{
public void Configuration(IAppBuilder app)
{
var config = this.GetInjectionConfiguration();
BootstrapperWebApi bootstrapperWebApi = (BootstrapperWebApi)this.GetBootstrapperWebApi(config);
bootstrapperWebApi.Initialize(true)
.EnableLogging()
.DisableWebApiDefaultExceptionHandler();
WebApiConfig.Register(config);
app.UseOwinExceptionHandler();
app.Use<LoggerMiddleware>();
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
//others stuff
}
Я знаю, что это старый пост, но я прошел через ту же проблему.
В моей ситуации CORS установлен как для OWIN, так и для WebAPI. Промежуточное ПО OWIN CORS перехватывало вызов OPTIONS задолго до того, как оно попало в WebAPI. Может быть, это хорошо поможет кому-то еще в будущем.
В моем случае я сделал это:
<verbs allowUnlisted="true" applyToWebDAV="true">
<remove verb="OPTIONS"/>
<add verb="OPTIONS" allowed="true"/>
</verbs>
</requestFiltering>
</security>
Когда я добавил <add verb="OPTIONS" allowed="true"/>
в web.config, приложение не удалось запустить с этой ошибкой
HTTP Error 500.19 - Internal Server Error
The requested page cannot be accessed because the related configuration data for the page is invalid.
Cannot add duplicate collection entry of type 'add' with unique key attribute 'verb' set to 'OPTIONS'
Поэтому мне пришлось сначала удалить его.
Для меня с IIS 10 и PHP 8.0 ни один другой ответ не работал, это были просто ограничения глагола обработчика php-cgi. потому что глаголы php-cgi по умолчанию были POST,GET, HEAD. Я исправил это следующим образом:
<handlers>
<remove name="PHP_via_FastCGI" />
<add name="PHP_via_FastCGI" path="*.php" verb="*" modules="FastCgiModule" scriptProcessor="C:\Program Files\iis express\PHP\v8.0\php-cgi.exe" resourceType="Either" requireAccess="Script" />
</handlers>
У меня такая же проблема. Запрос OPTIONS возвращает статус 200 OK, но не содержит заголовка Access-Control-Allow-Origin. Проблема заключалась в том, что сетевая политика нашего клиента блокировала запрос глагола OPTIONS и отвечала на предупреждающее сообщение со статусом 200 OK. Я знаю, что это старый пост, но я хочу поделиться своим делом для всех, кто в нем нуждается.
Просто следуйте изображениям ниже, чтобы разблокировать цвета в IIS.
введите описание изображения здесь
введите описание изображения здесь
введите описание изображения здесь
введите описание изображения здесь