2014-05-05 255 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響應)。 –