基于jQuery AJAX SOAP的Web服务和CORS(跨域资源共享)

Ian*_*ram 16 jquery soap web-services cors

我已经有几个星期了,试图让我的一个基于jQuery AJAX SOAP的跨域Web服务从我为我的一个客户编写的jQuery插件中工作.我所做的大部分研究似乎都表明这是不可能的,因为CORS或Cross Origin Resource Sharing只允许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>
Run Code Online (Sandbox Code Playgroud)

我的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"
});
}
Run Code Online (Sandbox Code Playgroud)

non*_*lar 5

"这是不可能的,因为CORS或Cross Origin Resource Sharing只允许jasonP(GET)类型的呼叫."

CORS不仅限于GET方法,也不仅限于JSONP风格的调用.

JSONP是Web开发人员在CORS标准化之前使用的一种技术,用于向除了为页面提供服务的主机之外的主机执行AJAX请求.JSONP通过<script>在页面中插入标记来工作.它需要服务器参与,通常是通过将JSON结果包装在对函数的调用中,通过callback参数在AJAX调用中命名.看到这个答案: 什么是jsonp-all-about.

正如您所指出的,JSONP仅限于执行GET方法,因为 <script>只执行GET.它还有其他问题,例如无法处理错误.例如,如果返回400响应,则浏览器不会执行脚本,而是执行AJAX调用的JS错误处理程序.

CORS是一个较新的标准.这还需要服务器的参与,因为它必须处理的飞行前检查,并使用额外的HTTP标头,如:Access-Control-Allow-Origin,Access-Control-Allow-Methods,和Access-Control-Allow-Headers,你在编辑描述以及你的问题.它不仅限于GET方法.相反,它仅限于Access-Control-Allow-Methods标题中预检检查结果指定的那些方法.CORS不需要在回调函数中包含结果或对结果进行任何其他调整,它会处理错误和其他状态代码.有关更多信息,请参阅CORS的这一优秀概述.