2014-05-05 14 views
5

Tôi đã thấy rất nhiều câu hỏi về SO về điều này, nhưng tôi không thể tìm thấy những gì còn thiếu trong mã của mình.jQuery .ajax() 405 (Phương pháp không được phép)/Tên miền chéo

Tôi đang triển khai CORS vì tôi không muốn sử dụng JSONP.

Tôi biết đây là preflighted request và tôi nghĩ rằng tôi đang thêm đúng headers.

Lỗi này là rằng các trang web dường như không thích tôi WCF và mỗi khi tôi làm một yêu cầu, một phương pháp OPTION gọi được thực hiện ngay cả tho Tôi có Access-Control-Allow-Methods tiêu đề.

tôi chỉ muốn thực hiện cuộc gọi POST để WCF của tôi với một contentType: "application/json",

Các WCF được tự tổ chức, các ứng dụng web là trên IIS 7.5.


gì Chrome sẽ hiển thị:

enter image description here


gì show cáy enter image description here


Hợp đồng

<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 
    } 
}); 

Trên WCF Tôi có xử lý sau, theo 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 

Xin lỗi cho đăng bài dài, tôi muốn trở thành cụ thể.

Xin cảm ơn trước.


CẬP NHẬT

Nếu tôi sử dụng contentType: "text/plain" tôi nhận được lỗi trên chrome console:

POST http://192.168.0.61:8282/Project.Services.Person/LookUpPerson 400 (Bad Request)

+0

Không thể tìm thấy bất cứ điều gì tốt để giúp nhưng tìm thấy [this] (http://www.israelaece.com/post/Introducao-ao-CORS.aspx) đăng bài về CORS nơi dữ liệu được gửi trong 'OPTIONS' là khác với của bạn. Có lẽ nó cung cấp cho bạn một đầu mối nhưng không chắc chắn nếu đó là những từ đồng nghĩa cho cùng một điều bạn đã viết. –

+0

@VitorCanova cảm ơn, hãy kiểm tra. – Luis

+0

Tôi đã không làm điều này với WCF nhưng tôi có với WebAPI. Khi tôi nhận được 400 yêu cầu xấu, đó là vì tôi đã ném một ngoại lệ bên trong phương thức của tôi trên máy chủ. Bạn có thể đính kèm một trình gỡ lỗi vào mã WCF và xem yêu cầu và bước qua? –

Trả lời

9

tôi đã cùng vấn đề và điều này đã sửa nó cho tôi.

Thay đổi

[WebInvoke(Method = "Post")] 

để

[WebInvoke(Method = "*")] 

vì mặc dù bạn chấp nhận POST, trình duyệt hiện đại sẽ luôn gửi OPTIONS.

+0

Gonna kiểm tra xem nó ra – Luis

+0

Với '" * "' Nó cho phép tôi tiếp cận với máy chủ, nhưng tôi nhận được một lỗi mới với một yêu cầu xấu. Cảm ơn tho – Luis

+0

Một khi bạn nhận được điều này đến nay (xử lý đúng yêu cầu CORS vv), bạn vẫn cần thêm một mục nữa. Một số mã như 'if (WebOperationContext.Current.IncomingRequest.Method ==" OPTIONS ") trả về null; ' trong phương thức dịch vụ sao cho nó sẽ không hủy bỏ (tạo ra 400 phản hồi) trong khi gọi trước chuyến bay. –

Các vấn đề liên quan