跨域AJAX请求无效

Don*_*Don 13 ajax jquery jsonp cross-domain cors

我在第三方API上调用POST,我一直在使用jQuery的$ .ajax函数.但是,当我拨打电话时,我收到以下错误:XMLHttpRequest cannot load http://the-url.com. The request was redirected to 'http://the-url.com/anotherlocation', which is disallowed for cross-origin requests that require preflight.

我在这篇文章中看到这可能是一个Webkit错误,所以我在Firefox中尝试过它(我在Chrome中开发)并得到了相同的结果.我在Chrome和Firefox上尝试了这个,我得到了相同的结果.

根据这篇文章,我也尝试使用jsonp crossDomain将$ .ajax函数的属性true设置为并设置dataTypejsonp.但是,这导致500内部服务器错误.

当我使用--disable-web-security标志启动Chrome时,我没有任何问题.但是,如果我正常启动浏览器,那么我会收到错误.

所以,我想这可能是一个由两部分组成的问题.我该怎么做才能提出这个跨域请求?如果答案是JSONP,那么我该如何确定第三方API是否设置正确以支持这一点?

编辑:这是我在禁用浏览器安全性的情况下拨打电话的屏幕截图:https://drive.google.com/file/d/0Bzo7loNBQcmjUjk5YWNWLXM2SVE/edit?usp =sharing

这是我在启用浏览器安全性的情况下拨打电话时的屏幕截图(正常情况下):https://drive.google.com/file/d/0Bzo7loNBQcmjam5NQ3BKWUluRE0/edit?usp=sharing

ara*_*ind 20

对于你的第一个问题,

我该怎么做才能提出这个跨域请求?

首先将以下请求标头发送到服务器.根据响应标头,UserAgent(即此处的浏览器)将丢弃响应(如果有),并且当标头未加起来时不将其返回到XHR回调.

Origin: http://yourdomain.com Access-Control-Request-Method: POST Access-Control-Request-Headers: X-Custom-Header

然后,您的服务器应使用以下标头进行响应:

Access-Control-Allow-Origin: http://yourdomain.com Access-Control-Allow-Methods: GET, POST, OPTIONS Access-Control-Allow-Headers: X-Custom-Header

示例取自 - /sf/answers/608253271/

您可以使用Fiddler或Web Inspector Network选项卡(Chrome)或Firebug的网络选项卡等工具查找服务器发回的标头以响应您的请求.

第三方API服务器URL应使用支持的值进行响应.如果不是那就是你的问题.

在JsonP 500服务器错误中没有多大帮助,因为它说内部服务器错误


UPDATE

我看到了你的屏幕截图,这里有几点需要注意

  1. HTTP POST 用来
  2. Access-Control在两种模式响应中都找不到标头.第二个状态码为302
  3. Origin请求标题是null,所以我相信HTML文件是从文件系统而不是从网站打开的

启用JSONP

为了说明为什么JSONP不起作用,原因 - Web服务配置(指定的ASMX)没有GET为请求启用模式.JSONP无法使用POST.

为什么200禁用安全?

直接调用POST请求时没有OPTIONS或在它之前触发预检请求,因此服务器只会响应.

为什么302启用安全性的状态代码?

首先介绍一下安全标志未被禁用时的情况(默认).该OPTIONS请求被解雇的URL.URL应以可使用的,即HTTP方法的列表进行回应GET,POST等这的状态代码OPTIONS的请求应200.

在当前情况下,执行此操作时会调用重定向.并且重定向指向HTTP服务器错误的自定义错误处理程序.我相信这是404错误,它被捕获并重定向.[这可能是因为自定义处理程序设置为ResponseRedirect而不是ResponseRewrite] 404未启用跨域访问的原因.

如果关闭自定义错误处理,则会返回HTTP 500代码.我相信通过在触发跨域请求后立即检查服务器日志可以找到问题.最好检查服务器日志以查找除此之外的错误(如果有).

可能解决方案

要启用访问权限,有两种方法 - 详细说明.或者直接将访问控制头添加到web.config文件的customheaders部分.

启用跨域访问时,服务器应响应OPTIONS并允许请求通过.HTTP 200除非有其他错误,否则应该返回.但是ajax回调将无法访问响应.只有当Access-Control-Allow-Origin设置为"*"或Origin请求标头值时,Access-Control才能完成此操作.并且ajax回调将按预期收到响应.

第三点,null Origin.如果将Origin请求标头值作为发送回来,这将是一个问题Access-Control-Allow-Origin.但我假设您将HTML页面移动到Web服务器,所以这不应该是一个问题.

希望这可以帮助!

  • 是的,这是对的.您可以在网络选项卡上尝试从HTML页面中的CDN下载脚本,例如:http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js同样第三方API应根据需要启用Access-Control标头. (2认同)

Don*_*Don 3

我提出的解决方案是使用 cURL(如 @waki 提到的),但稍加修改的版本支持 SOAP。然后,我不是对第三方 API(配置不正确)进行 AJAX 调用,而是对本地 PHP 文件进行调用,然后该文件对第三方 API 进行 SOAP 调用,并将数据传递回我的 PHP 文件,这样我就可以然后处理它。这让我忘记了 CORS 以及与之相关的所有复杂性。这是代码(从这个问题中获取并修改,但没有身份验证)。

$post_data = "Some xml here";
$soapUrl = "http://yoursite.com/soap.asmx"; // asmx URL of WSDL


$headers = array(
    "Content-type: text/xml;charset=\"utf-8\"",
    "Accept: text/xml",
    "Cache-Control: no-cache",
    "Pragma: no-cache",
    "SOAPAction: http://yoursite.com/SOAPAction",
    "Content-length: " . strlen($post_data),
); //SOAPAction: your op URL

$url = $soapUrl;

// PHP cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); // the SOAP request
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$response = curl_exec($ch);

/* Check for an error when processing the request. */
if(curl_errno($ch) != 0) {
   // TODO handle the error
}

curl_close($ch);

// TODO Parse and process the $response variable (returned as XML)
Run Code Online (Sandbox Code Playgroud)