我在第三方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
答案 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服务器错误中可以提供很多帮助,因为它说内部服务器错误
<强>更新强>
我看到了你的屏幕截图,这里有几件需要注意的事情
HTTP POST
Access-Control
个标头。第二个状态代码为302
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
] {{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变量中,您可以获得数据。