跨域AJAX请求无效

时间:2014-03-13 20:04:31

标签: jquery ajax cross-domain jsonp 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.

我从this post看到这可能是一个Webkit错误,所以我在Firefox中尝试过(我在Chrome中开发)并得到了相同的结果。我试过这个Chrome和Firefox和我得到了相同的结果。

this post,我还尝试使用jsonp将$ .ajax函数的crossDomain属性设置为true并将dataType设置为jsonp }。但是,这导致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

3 个答案:

答案 0 :(得分: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

取自 - https://stackoverflow.com/a/8689332/1304559

的示例

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

第三方API服务器网址应使用支持的值进行回复。如果它不是你的问题。

在JsonP 500服务器错误中可以提供很多帮助,因为它说内部服务器错误


<强>更新

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

  1. 使用HTTP POST
  2. 在两种模式响应中都找不到Access-Control个标头。第二个状态代码为302
  3. Origin请求标头为null,因此我认为HTML文件是从文件系统而不是从网站打开的
  4. 启用JSONP

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

    为什么200已禁用安全性?

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

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

    首先说明未禁用安全标志时的情况(默认)。 OPTIONS请求被触发到URL。该URL应使用可以使用的HTTP方法列表进行回复,即GETPOST等。此OPTIONS请求的状态代码应为200

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

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

    可能的解决方案

    要启用访问权限,有两种方式 - detailed here。或者直接将访问控制标题添加到HTTP 500文件的web.config部分。

    启用跨域访问时,服务器应响应OPTIONS并允许请求通过。除非存在其他错误,否则应返回customheaders。但是ajax回调将无法访问响应。只有当HTTP 200设置为&#34; *&#34;时才能完成此操作。或者Access-Control-Allow-Origin请求标头值,以及Origin根据需要。并且ajax回调将按预期收到响应。

    第三点,null Access-Control。如果将Origin请求标头值作为Origin发回,则会出现问题。但我假设您将HTML页面移动到Web服务器,因此不应该成为问题。

    希望这有帮助!

答案 1 :(得分:3)

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

$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)

答案 2 :(得分:1)

你可以使用cURL吗? 使用Ajax,您可以将数据发送到处理程序(在服务器上,名为callback.php)。 在您的文件(callback.php)中使用cURL和您的数据:

$post_data = array( 
    'key' => 'key', 
    'test' => 'text'
    ); 

$curl = curl_init(); 
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); 
curl_setopt($curl, CURLOPT_POST, TRUE); 
curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data);  
curl_setopt($curl, CURLOPT_URL, 'http://www.domain.com/'); 
$return = json_decode(trim(curl_exec($curl)), TRUE); 
curl_close($curl); 

在$ return变量中,您可以获得数据。

相关问题