我正在尝试从 JQuery 调用 C# WCF SOAP Web 服务。
该服务托管在端口 80 上的 IIS 上,客户端从端口 81 上的 Apache 运行,两者均来自 localhost。所以我陷入了跨源请求。
使用 Chrome,我得到了预期的结果,但查看网络流量,它显示
OPTIONS
请求返回错误400 Bad Request
,但是下一个POST
请求成功:使用 Firefox,会引发错误(JavaScript 警报显示
null | error |
)。看来POST
请求未发送,因为OPTIONS
请求失败:使用 IE,一切正常,就好像它来自同一个源一样...我没有看到任何
OPTIONS
请求:
接口(interface)暴露的函数:
namespace Test
{
[ServiceContract]
public interface IMathService
{
[OperationContract]
String HelloWorld();
}
}
服务配置(Web.config):
<services>
<service name="Test.MathService" behaviorConfiguration="ServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:80/WCFtest/service.svc" />
</baseAddresses>
</host>
<endpoint address="/soap" binding="basicHttpBinding" contract="Test.IMathService" />
<endpoint address="/rest" binding="webHttpBinding" contract="Test.IMathService" behaviorConfiguration="WEB" />
</service>
</services>
[...]
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="http://localhost:81" />
<add name="Access-Control-Allow-Headers" value="SOAPAction, Content-type, Accept, Origin" />
<add name="Access-Control-Allow-Methods" value="POST, GET, PUT, DELETE, OPTIONS" />
</customHeaders>
</httpProtocol>
JQuery 代码:
$('#btn_helloworld').click(function () {
var soapRequest = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/">' +
'<soapenv:Header/>' +
'<soapenv:Body>' +
'<tem:HelloWorld/>' +
'</soapenv:Body>' +
'</soapenv:Envelope>';
$.ajax({
type: 'POST',
url: 'http://localhost/WCFtest/service.svc/soap',
crossDomain: true,
contentType: 'text/xml',
dataType: 'xml',
data: soapRequest,
beforeSend: function (xhr) {
xhr.setRequestHeader('SOAPAction', 'http://tempuri.org/IMathService/HelloWorld');
},
success: function (data) {
$('#outputHelloWorld').val($(data).find('HelloWorldResponse').text());
},
error: function (jqxhr, textStatus, errorThrown) {
alert(jqxhr.responseXML + ' | ' + textStatus + ' | ' + errorThrown);
}
});
});
如果从同一来源调用,服务工作正常。
我错过了什么吗?
最佳答案
我自己花了两天时间追鬼(浏览器对 CORS 的各种“解释”版本),我认为结论是:这里的问题是 OPTIONS 请求 - FF 和 Opera 正在发送它,但我不认为IE 确实如此。另外,我不认为 OPTIONS 是 IIS、IIS Express 等默认允许的动词。 我在我的 global.asax 中添加了 Application_BeginRequest:
void Application_BeginRequest(Object sender, EventArgs e)
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*");
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "*");
HttpContext.Current.Response.End();
}
}
结果我成功地通过了 FF 的请求。
关于jquery - 从 JQuery 调用 WCF 服务 : cross-origin OPTIONS request gives error 400,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18874320/