【发布时间】:2014-06-22 05:51:39
【问题描述】:
我在 SO 上看到了很多关于此的问题,但我找不到我的代码中缺少的内容。
我正在实施CORS,因为我不想使用JSONP。
我知道这是preflighted request,我想我添加的是正确的headers。
错误是该网站似乎不喜欢我的WCF,并且每次我发出请求时,即使我有Access-Control-Allow-Methods 标头,也会调用OPTION 方法。
我只想用contentType: "application/json", 给我的WCF 打一个POST 电话
WCF 是自托管的,网络应用程序位于 IIS 7.5。
Chrome 显示的内容:
提琴手展示了什么
合同
<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
}
});
根据http://enable-cors.org/server_wcf.html,在 WCF 上,我有以下处理程序
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
抱歉,帖子太长了,我想具体一点。
提前致谢。
更新
如果我使用 contentType: "text/plain",我会在 chrome 控制台上收到错误消息:
POST
http://192.168.0.61:8282/Project.Services.Person/LookUpPerson400(错误请求)
【问题讨论】:
-
找不到任何有用的帮助,但找到了关于 CORS 的 this 帖子,其中
OPTIONS中发送的数据与您的不同。也许它会给你一个线索,但不确定这些是否是你写的同一件事的同义词。 -
@VitorCanova 谢谢,去看看。
-
我还没有用 WCF 做到这一点,但我用 WebAPI 做到了。当我收到 400 Bad Request 时,这是因为我在服务器上的方法中抛出了异常。您能否将调试器附加到 WCF 代码并查看请求并逐步执行?
-
@ErikNoren 是的,我在方法上有一个断点,但它没有被触发
标签: javascript jquery ajax json wcf