2014-05-05 208 views
5

我已经看到这么多关于这个问题,但我找不到我的代码中缺少的东西。我正在执行CORS因为我不想使用JSONPjQuery .ajax()405(方法不允许)/跨域

我知道这是一个preflighted request,我想我正在添加正确的headers

错误是,网站似乎并不喜欢我的WCF和每次我做请求时,即使我有Access-Control-Allow-Methods标题,也会调用OPTION方法。

我只想做一个POST打到我WCFcontentType: "application/json",

WCF是自托管,网络应用是IIS 7.5


Chrome浏览器怎么显示:

enter image description here


什么小提琴手表演 enter image description here


合同

<OperationContract()> 
<WebInvoke(Method:="POST", 
      RequestFormat:=WebMessageFormat.Json, 
      ResponseFormat:=WebMessageFormat.Json, 
      BodyStyle:=WebMessageBodyStyle.WrappedRequest)> 
<FaultContract(GetType(ServiceFault))> 
Function LookUpPerson(person As Person) _ 
        As List(Of Person) 

的app.config

<serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" /> 
<bindings> 
    <webHttpBinding> 
    <binding name="webHttpBindingWithJsonP" 
      crossDomainScriptAccessEnabled="true"> 
     <security mode="None" /> 
    </binding> 
    </webHttpBinding> 
</bindings> 

<services> 
    <service name="Project.Services.Person"> 
    <endpoint address="ws" binding="wsHttpBinding"  contract="Project.Services.Interfaces.IPublic" /> 
    <endpoint address="" binding="webHttpBinding" contract="Project.Services.Interfaces.IPublic" 
       behaviorConfiguration="jsonBehavior"/> 
    <host> 
     <baseAddresses> 
     <add baseAddress="http://localhost:8732/" /> 
     </baseAddresses> 
    </host> 
    </service> 
</services> 

<extensions> 
    <behaviorExtensions> 
    <add name="customHeaders" 
     type="Project.Services.Utilities.EnableCrossOriginResourceSharingBehavior, Project.Services, Version=1.0.0.0, Culture=neutral"/> 
    </behaviorExtensions> 
</extensions> 

<endpointBehaviors> 
    <behavior name="jsonBehavior"> 
    <webHttp/> 
    <customHeaders /> 
    </behavior> 
</endpointBehaviors> 

的JavaScript

$.ajax({ 
    url: "http://192.168.0.61:8282/Project.Services.Person/LookUpPerson", 
    type: "POST", 
    contentType: "application/json", 
    crossDomain: true, 
    dataType: "json", 
    data: { person: JSON.stringify(person) }, 
    success: function (data) { 
     // doing something 
    }, 
    error: function (error) { 
     // doing something 
    } 
}); 

在WCF我有以下处理程序,根据http://enable-cors.org/server_wcf.html

Public Class CustomHeaderMessageInspector 
     Implements IDispatchMessageInspector 

     Private requiredHeaders As Dictionary(Of String, String) 
     Public Sub New(headers As Dictionary(Of String, String)) 
      requiredHeaders = If(headers, New Dictionary(Of String, String)()) 
     End Sub 

     Public Function AfterReceiveRequest(ByRef request As System.ServiceModel.Channels.Message, 
              channel As System.ServiceModel.IClientChannel, 
              instanceContext As System.ServiceModel.InstanceContext) _ 
             As Object _ 
             Implements System.ServiceModel.Dispatcher.IDispatchMessageInspector.AfterReceiveRequest 
      Return Nothing 
     End Function 

     Public Sub BeforeSendReply(ByRef reply As System.ServiceModel.Channels.Message, 
            correlationState As Object) _ 
           Implements System.ServiceModel.Dispatcher.IDispatchMessageInspector.BeforeSendReply 
      Dim httpHeader = TryCast(reply.Properties("httpResponse"), HttpResponseMessageProperty) 
      For Each item In requiredHeaders 
       httpHeader.Headers.Add(item.Key, item.Value) 
      Next 
     End Sub 

    End Class 

Public Class EnableCrossOriginResourceSharingBehavior 
     Inherits BehaviorExtensionElement 
     Implements IEndpointBehavior 

     Public Sub AddBindingParameters(endpoint As ServiceEndpoint, bindingParameters As System.ServiceModel.Channels.BindingParameterCollection) _ 
             Implements System.ServiceModel.Description.IEndpointBehavior.AddBindingParameters 

     End Sub 

     Public Sub ApplyClientBehavior(endpoint As ServiceEndpoint, clientRuntime As System.ServiceModel.Dispatcher.ClientRuntime) _ 
             Implements System.ServiceModel.Description.IEndpointBehavior.ApplyClientBehavior 

     End Sub 

     Public Sub ApplyDispatchBehavior(endpoint As ServiceEndpoint, endpointDispatcher As System.ServiceModel.Dispatcher.EndpointDispatcher) _ 
             Implements System.ServiceModel.Description.IEndpointBehavior.ApplyDispatchBehavior 
      Dim requiredHeaders = New Dictionary(Of String, String)() 

      requiredHeaders.Add("Access-Control-Allow-Origin", "*") 
      requiredHeaders.Add("Access-Control-Allow-Methods", "POST, GET, OPTIONS") 
      requiredHeaders.Add("Access-Control-Allow-Headers", "Origin, Content-Type, Accept") 
      requiredHeaders.Add("Access-Control-Max-Age", "1728000") 

      endpointDispatcher.DispatchRuntime.MessageInspectors.Add(New CustomHeaderMessageInspector(requiredHeaders)) 
     End Sub 

     Public Sub Validate(endpoint As ServiceEndpoint) _ 
      Implements System.ServiceModel.Description.IEndpointBehavior.Validate 

     End Sub 

     Public Overrides ReadOnly Property BehaviorType() As Type 
      Get 
       Return GetType(EnableCrossOriginResourceSharingBehavior) 
      End Get 
     End Property 

     Protected Overrides Function CreateBehavior() As Object 
      Return New EnableCrossOriginResourceSharingBehavior() 
     End Function 

    End Class 

对不起,长的帖子,我想是具体的。

在此先感谢。


UPDATE

如果我使用contentType: "text/plain"我得到错误的铬控制台上:

POST http://192.168.0.61:8282/Project.Services.Person/LookUpPerson 400(错误请求)

+0

Could'nt找到什么好的帮助,但发现[这](http://www.israelaece.com/post/Introducao-ao-CORS.aspx)发布关于CORS其中在'OPTIONS'发送的数据是不同于你的。也许它给了你一个线索,但不知道这些是否是你写的同一事物的同义词。 –

+0

@VitorCanova谢谢,会检查出来。 – Luis

+0

我没有用WCF做过这个,但是我已经用了WebAPI。当我得到了400个错误的请求时,这是因为我在服务器上的方法中抛出了一个异常。您是否能够将调试器附加到WCF代码并查看请求并逐步完成? –

回答

9

我有同样的问题,并为我解决了这个问题。

变化

[WebInvoke(Method = "Post")] 

[WebInvoke(Method = "*")] 

因为虽然你接受POST,现代的浏览器总是会发送OPTIONS

+0

要去看看 – Luis

+0

使用'“*”'这让我到达服务器,但我发现了一个新的错误与错误的请求。感谢你 – Luis

+0

一旦你得到这个(正确处理CORS请求等),你仍然需要一个项目。一些代码如 if(WebOperationContext.Current.IncomingRequest.Method ==“OPTIONS”) 返回null;服务方法中的“ ”,以便在飞行前呼叫期间不会中止(生成400响应)。 –