我在StackOverflow中已经阅读了很多类似的问题,但这些解决方案并不适用于我。
我有WCF REST服务:
[<OperationContract>]
[<WebInvoke(UriTemplate = "PostItem",
RequestFormat= WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json, Method = "POST")>]
我可以使用Postman(Chrome扩展程序)使用它。我将数据传递为'raw',而不是'urlencoded'。我得到200返回代码。
我需要使用angularjs调用此方法:
$http.post('http://192.168.1.65/Service1.svc/restapi/PostItem',
{
"Address": "г. Москва, ул. Соколово-Мещерская, д.25",
...
"User": ""
})
我刚从Postman复制了URL和JSON。但是我得到了错误:
angular.js:10722选项 http://192.168.1.65/Service1.svc/restapi/PostItem http://192.168.1.65/Service1.svc/restapi/PostItem。回应 预检具有无效的HTTP状态代码405
我搜索过类似的问题并找到了两个解决方案:
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扩展可以成功调用此方法。
如何使用AngularJS进行相同的POST调用?
更新:
这是OPTIONS请求:
审核和响应标签为空
更新2:
一切正常,但在Chrome中无效。
答案 0 :(得分:24)
即使是封闭的问题,我想展示一下对我有用的东西。
首先你必须在web.config上启用CORS(就像Mihai sad):
<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();
}
}
答案 1 :(得分:7)
看起来我找到了解决方案。我刚刚添加了第二种方法:
[<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 :(得分:1)
虽然这已经有了答案,但继续我的解决方案。
在Web配置中,您必须删除指令export abstract class Collection<T> {
protected _collection: Map<number, T>;
public hydrate(key: number, item: T): this {
this._collection.set(key, item);
return this;
}
...
}
export class Tours extends Collection<Tour> { }
首先添加customHeaders
<remove name="OPTIONSVerbHandler" />
然后注释掉或删除指令以删除OPTIONSverbHandler
<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>
答案 3 :(得分:0)
由于IIS团队发布了IIS CORS module黑客,因此不再需要空方法了。它正确处理包括预检请求在内的CORS。您可以在Web配置中配置它,例如:
<?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>
答案 4 :(得分:0)
我刚刚在AJAX请求中删除stmt.c
时解决了同样的问题。如果有人在代码中有一个,请尝试将其删除。
答案 5 :(得分:0)
对我有用的解决方案:
将其添加到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文件(全局应用程序类)并添加以下代码:
protected void Application_BeginRequest(object sender, EventArgs e){
if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
{
Response.Flush();
}
}