基于 jQuery AJAX SOAP 的 Web 服务和 CORS(跨源资源共享) [英] jQuery AJAX SOAP based web services and CORS (cross origin resource sharing)
问题描述
几个星期以来,我一直试图通过我为我的一位客户编写的 jQuery 插件使我的一项基于 jQuery AJAX SOAP 的跨域 Web 服务能够工作.我所做的大部分研究似乎都表明这是不可能的,因为 CORS 或跨源资源共享只允许 jasonP (GET) 类型的调用.
I have for a few weeks now been trying to get one of my jQuery AJAX SOAP based cross domain web service to work from a jQuery plugin I have written for one of my customers. Most of the research I did seemed to indicate that it was not possible because CORS or Cross Origin Resource Sharing would only allow jasonP (GET) type calls.
我终于想出了如何让它发挥作用,并认为我会分享我必须做的事情.
首先要了解的是,在 CORS 感知浏览器中,服务器位于另一个域中,GET(以及其他参数)以外的任何其他内容都将导致所谓的预检.这意味着浏览器将向服务器询问允许执行的选项列表.除非服务器返回允许基于 SOAP 的 Web 服务的确切选项列表,否则即使在发出实际请求之前调用也会失败.
The first thing to understand is that in a CORS aware browser, where the server is in another domain, anything other that a GET (amongst other parameters) will result in what is called a preflight check. What this means is that the browser will ask the server for a list of options that it is allowed to perform. Unless the server returns the exact list of options to allow a SOAP based web service the call will fail even before the actual request is made.
您需要做的是使 Web 服务器(在我的示例中为 IIS7.5)返回正确的选项列表.
您可以通过在 inetpubwwwroot 文件夹中配置 web.config 文件来完成此操作(如果您没有,只需创建它并将以下内容复制到其中).
What you need to do is to make the web server (in my example it's IIS7.5) return the correct list of options.
You do this by configuring the web.config file in the inetpubwwwroot folder (if you don't have one just create it and copy the following into it).
我的 web.config 文件看起来像这样.
My web.config file looks like this.
重要的一切都区分大小写一旦我意识到这一切都按预期工作.
Important everything is case sensitive once I realized this everything just worked as expected.
<?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 代码如下所示.
My jQuery AJAX code looks like this.
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"
});
}
推荐答案
这是不可能的,因为 CORS 或跨源资源共享只允许 jasonP (GET) 类型的调用."
CORS 不仅限于 GET 方法,也不限于 JSONP 样式的调用.
CORS is not limited to GET methods, nor is it it limited to JSONP-style calls.
JSONP 是 Web 开发人员在 CORS 标准化之前使用的一种技术,用于向除为页面提供服务的主机之外的主机执行 AJAX 请求.JSONP 通过在页面中插入 标签来工作.它需要服务器参与,通常通过将 JSON 结果包装在对函数的调用中,通过
callback
参数在 AJAX 调用中命名.请参阅此答案:what-is-jsonp-all-about.
JSONP is a technique that web developers used before CORS was standardized, to perform AJAX request to hosts other than the one that served the page. JSONP works by inserting a <script>
tag into the page. It requires server participation, usually by wrapping the JSON results in a call to a function, named in the AJAX call via a callback
parameter. See this answer: what-is-jsonp-all-about.
正如您所指出的,JSONP 仅限于执行 GET 方法,因为 仅执行 GET.它也有其他问题,例如无法处理错误.例如,如果返回 400 响应,则浏览器根本不会执行该脚本,而不会为 AJAX 调用执行 JS 错误处理程序.
As you pointed out, JSONP is limited to performing a GET method, because <script>
only performs a GET. It has other problems, too, such as not being able to handle errors. For example, if a 400 response is returned, the script is simply not executed by the browser, rather than executing a JS error handler for the AJAX call.
CORS 是较新的标准.它还需要服务器参与,因为它必须处理预检检查,并使用额外的 HTTP 标头,例如:Access-Control-Allow-Origin
、Access-Control-Allow-Methods
和 Access-Control-Allow-Headers
,您在编辑问题时对其进行了很好的描述.它不限于 GET 方法.相反,它仅限于由 Access-Control-Allow-Methods
标头中的预检结果指定的那些方法.CORS 不需要将结果包装在回调函数中或对结果进行任何其他调整,它会处理错误和其他状态代码.请参阅这篇出色的CORS 概述,了解更多信息.
CORS is a newer standard. It also requires server participation, in that it must handle the preflight check, and uses extra HTTP headers such as: Access-Control-Allow-Origin
, Access-Control-Allow-Methods
, and Access-Control-Allow-Headers
, which you described well in the edit to your question. It is not limited to GET methods. Rather, it is limited to those methods specified by the results of the preflight check in the Access-Control-Allow-Methods
header. CORS does not require the wrapping of results in a callback function or any other adjustment to the results, and it handles errors and other status codes. See this excellent overview of CORS for more information.
这篇关于基于 jQuery AJAX SOAP 的 Web 服务和 CORS(跨源资源共享)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!