Ответ на предполетный период имеет недопустимый код статуса HTTP 405
Я прочитал много подобных проблем в StackOverflow, но решения для меня не работают.
У меня есть служба WCF REST:
[<OperationContract>]
[<WebInvoke(UriTemplate = "PostItem",
RequestFormat= WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json, Method = "POST")>]
Я могу использовать его, используя Postman (расширение Chrome). Я передаю данные как "сырые", а не "urlencoded". И я получаю 200 код возврата.
![введите описание изображения здесь]()
Мне нужно вызвать этот метод, используя angularjs:
$http.post('http://192.168.1.65/Service1.svc/restapi/PostItem',
{
"Address": "г. Москва, ул. Соколово-Мещерская, д.25",
...
"User": ""
})
Я только что скопировал URL и JSON из Postman. Но я получаю сообщение об ошибке:
angular.js: 10722 ВАРИАНТЫ http://192.168.1.65/Service1.svc/restapi/PostItem http://192.168.1.65/Service1.svc/restapi/PostItem. Ответ для preflight имеет недопустимый код статуса HTTP 405
Я искал похожие проблемы и нашел два решения:
- Используйте jQuery для установки заголовка
Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
, но он не работает с моей службой WCF
-
Установите собственные заголовки в моем Web.Config:
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
</customHeaders>
</httpProtocol>
Мне это не помогает. И я не уверен, что причина ошибки на стороне сервера. Расширение Postman может успешно вызвать этот метод.
Как я могу сделать тот же POST-вызов, используя AngularJS?
Обновление
Вот запрос OPTIONS:
![введите описание изображения здесь]()
Вкладки просмотра и ответа пустые
Обновление 2:
Все работает отлично в IE, но не работает в Chrome.
Ответы
Ответ 1
Похоже, я нашел решение. Я просто добавил второй метод:
[<OperationContract>]
[<WebInvoke(UriTemplate = "PostTest",
RequestFormat= WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json, Method = "POST")>]
abstract PostTest: obj: Test -> unit
[<OperationContract>]
[<WebInvoke(UriTemplate = "PostTest",
RequestFormat= WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json, Method = "OPTIONS")>]
abstract PostTestOptions: unit -> unit
Это просто пустые методы, которые ничего не делают. Я не знаю причины, но все работает.
Ответ 2
Я хочу показать, что работа для меня.
Сначала вы должны включить CORS на web.config
(как Михай грустный):
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
</customHeaders>
</httpProtocol>
Если у вас есть дополнительный параметр HEADER, вы должны добавить его в Access-Control-Allow-Headers, например:
<add name="Access-Control-Allow-Headers" value="Content-Type, X-Your-Extra-Header-Key" />
И, наконец, для обработки запросов OPTIONS вы должны ответить пустым ответом, добавив в свой класс приложения:
protected void Application_BeginRequest()
{
if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
{
Response.Flush();
}
}
Ответ 3
Хотя у этого уже есть ответ, но это мое решение.
В веб-конфигурации вы должны удалить инструкцию до <remove name="OPTIONSVerbHandler" />
Сначала добавьте в customHeaders
<httpProtocol>
<!-- THESE HEADERS ARE IMPORTANT TO WORK WITH CORS -->
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="POST, PUT, DELETE, GET, OPTIONS" />
<add name="Access-Control-Allow-Headers" value="content-Type, accept, origin, X-Requested-With, X-Authentication, name" />
</customHeaders>
</httpProtocol>
Затем либо закомментируйте или удалите инструкцию для удаления OPTIONSverbHandler
<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>
Ответ 4
Поскольку IIS Team опубликовала модуль IIS CORS, взломам как пустые методы больше не нужны. Он имеет дело с CORS, включая предполетные запросы. Вы можете настроить его в веб-конфигурации, например:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<cors enabled="true" failUnlistedOrigins="true">
<add origin="*" />
<add origin="https://*.microsoft.com"
allowCredentials="true"
maxAge="120">
<allowHeaders allowAllRequestedHeaders="true">
<add header="header1" />
<add header="header2" />
</allowHeaders>
<allowMethods>
<add method="DELETE" />
</allowMethods>
<exposeHeaders>
<add header="header1" />
<add header="header2" />
</exposeHeaders>
</add>
<add origin="http://*" allowed="false" />
</cors>
</system.webServer>
</configuration>
Ответ 5
Я только что решил ту же проблему с удалением xhr.setRequestHeader()
в моем запросе AJAX. Если у кого-то есть код, попробуйте удалить его.
Ответ 6
Решение, которое сработало для меня:
Добавьте это в web.config (на стороне сервера):
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
</customHeaders>
</httpProtocol>
Создайте файл Global.asax (класс приложения Global) и добавьте следующий код:
protected void Application_BeginRequest(object sender, EventArgs e){
if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
{
Response.Flush();
}
}