Wcf webHttpBinding预检的响应具有无效的HTTP状态代码400

时间:2016-02-09 16:21:43

标签: c# wcf google-chrome cors cross-domain

我关注了Ido Flatow的post来创建跨域请求并创建了以下内容:

在我的服务界面上:

[OperationContract]
[WebInvoke(Method = "*", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
bool GetUserAuthentication(string userLoginName, string password);

在app.config上:

<behaviors>
  <endpointBehaviors>
    <behavior name="webSupport">
      <webHttp />
      <CorsSupport />
    </behavior>
  </endpointBehaviors>
</behaviors>

<extensions>
  <behaviorExtensions>
    <add name="CorsSupport" type="WebHttpCors.CorsSupportBehaviorElement, WebHttpCors, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
  </behaviorExtensions>
</extensions>

现在我发送一个简单的帖子请求,使用角度$ http服务,它正在使用IE&amp; Edge(也在Postman上)但无法在Chrome&amp; Firefox出现以下错误:

  

XMLHttpRequest无法加载   http://localhost:5280/MetaDataService/GetUserAuthentication。响应   for preflight具有无效的HTTP状态代码400

Chrome错误打印屏幕:

Error

2 个答案:

答案 0 :(得分:7)

Chrome正在预检查找CORS标头的请求。如果请求是可接受的,它将发送实际请求。

我的问题是发送到我的WCF服务器的OPTIONS请求被拒绝我为我的方法定义了Method="*",导致选项请求被定向到我的方法并期望得到参数。

基于How to handle Ajax JQUERY POST request with WCF self-host问题的解决方案是添加新的OperationContract来处理OPTIONS请求:

[OperationContract]
[WebInvoke(Method = "OPTIONS", UriTemplate = "*")]
void GetOptions();

public void GetOptions()
{
}

此方法获取所有选项请求,并允许将真正的POST方法定向到我的服务方法。

答案 1 :(得分:0)

1.将此API添加到IRestService(您的服务接口)

[OperationContract]
[WebInvoke(Method = "OPTIONS", UriTemplate = "*")]
void Options();

2.在RestService(您的服务实现)

中实现此功能
public void Options()
{
    WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Origin", "*");
    WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
    WebOperationContext.Current.OutgoingResponse.Headers.Add("Access-Control-Allow-Headers", "Content-Type");
}

CORS操作

CORS世界中有两种类型的请求,“正常”请求和预检请求。正常请求是页面通常对服务发出的请求,附加标题“Origin”,表示原点,服务可以确定是否允许来自该来源的跨域调用(通过“访问” -Control-Allow-Origin“响应头”。 “安全”请求(GET和HEAD)仅使用额外的标头来工作。浏览器会将Origin标头添加到发往页面所在域以外的域的请求,如果该服务不允许该域,则该调用将失败。

“不安全”请求(例如POST,PUT或DELETE)不能以相同的方式完成。如果服务不支持CORS,它将忽略“Origin”标头并接受请求,可能产生副作用(例如,删除记录),并且在客户端获得响应时,浏览器仍然可以“失败“请求,但损坏已经完成。在这些情况下,浏览器的作用是首先发送预检请求,这是一个HTTP OPTIONS请求,要求获得发送实际请求的权限。如果服务应答允许呼叫的请求,则浏览器才会将用户请求发送给服务。