几个星期以来,我一直在尝试让我的一个基于 jQuery AJAX SOAP 的跨域 Web 服务从我为我的一位客户编写的 jQuery 插件中工作。我所做的大部分研究似乎表明这是不可能的,因为 CORS 或跨域资源共享只允许 jasonP (GET) 类型的调用。
我终于想出了如何让它发挥作用,并认为我会分享我必须做的事情。
首先要了解的是,在支持 CORS 的浏览器中,服务器位于另一个域中,除 GET 之外的任何其他参数(以及其他参数)都将导致所谓的预检检查。这意味着浏览器将向服务器询问允许执行的选项列表。除非服务器返回确切的选项列表以允许基于 SOAP 的 Web 服务,否则即使在发出实际请求之前,调用也会失败。
您需要做的是让 Web 服务器(在我的示例中为 IIS7.5)返回正确的选项列表。
为此,您可以在 inetpub\wwwroot 文件夹中配置 web.config 文件(如果没有,只需创建它并将以下内容复制到其中)。
我的 web.config 文件看起来像这样。
重要的是,一旦我意识到这一切都按预期工作,一切都是区分大小写的。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Methods" value="POST, GET, OPTIONS, PUT, DELETE" />
<add name="Access-Control-Allow-Headers" value="content-type,soapaction,x-requested-with" />
</customHeaders>
</httpProtocol>
<handlers accessPolicy="Read, Execute, Script" />
</system.webServer>
</configuration>
我的 jQuery AJAX 代码如下所示。
var getNextJobId = function()
{
var se = '';
se = se + '<?xml version="1.0" encoding="UTF-8" standalone="no"?>';
se = se + '<soap-env:Envelope xmlns:soap-env="http://www.w3.org/2003/05/soap-envelope">';
se = se + '<soap-env:Body>';
se = se + '<ebas:getNextJobIdRequest xmlns:ebas="http://www.ebasetech.com">';
se = se + '<ebas:ORGCODE>' + plugin.settings.orgcode + '</ebas:ORGCODE>';
se = se + '</ebas:getNextJobIdRequest>';
se = se + '</soap-env:Body>';
se = se + '</soap-env:Envelope>';
$.ajax(
{
url: params.webserviceTargetUrl,
beforeSend: function(xhr)
{
xhr.setRequestHeader("SOAPAction", "getNextJobId");
},
type: "POST",
dataType: "xml",
data: se,
crossDomain: true,
headers: {"X-Requested-With": "XMLHttpRequest"},
async: false,
success: function(xml)
{
params.jobId = $(xml).find("ebas\:JOBID").text();
},
failure: function(xml)
{
params.webserviceFailure = $(xml).text();
},
contentType: "charset=UTF-8"
});
}