如何通过JavaScript发送跨域POST请求?
注释-它不应该刷新页面,然后我需要抓取并解析响应。
如何通过JavaScript发送跨域POST请求?
注释-它不应该刷新页面,然后我需要抓取并解析响应。
当前回答
检查http://taiyolab.com/mbtweet/scripts/twitterapi_call.js中的post_method函数——这是上面描述的iframe方法的一个很好的例子。
其他回答
检查http://taiyolab.com/mbtweet/scripts/twitterapi_call.js中的post_method函数——这是上面描述的iframe方法的一个很好的例子。
如果您可以访问所有相关的服务器,请在另一个域请求的页面的回复标题中放入以下内容:
PHP:
header('Access-Control-Allow-Origin: *');
例如,在Drupal的xmlrpc.php代码中,你会这样做:
function xmlrpc_server_output($xml) {
$xml = '<?xml version="1.0"?>'."\n". $xml;
header('Connection: close');
header('Content-Length: '. strlen($xml));
header('Access-Control-Allow-Origin: *');
header('Content-Type: application/x-www-form-urlencoded');
header('Date: '. date('r'));
// $xml = str_replace("\n", " ", $xml);
echo $xml;
exit;
}
这可能会产生安全问题,您应该确保采取了适当的措施来验证请求。
我知道这是一个老问题,但我想分享我的方法。我使用cURL作为代理,非常简单和一致。创建一个名为submit.php的php页面,并添加以下代码:
<?
function post($url, $data) {
$header = array("User-Agent: " . $_SERVER["HTTP_USER_AGENT"], "Content-Type: application/x-www-form-urlencoded");
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($curl);
curl_close($curl);
return $response;
}
$url = "your cross domain request here";
$data = $_SERVER["QUERY_STRING"];
echo(post($url, $data));
然后,在你的js(这里是jQuery):
$.ajax({
type: 'POST',
url: 'submit.php',
crossDomain: true,
data: '{"some":"json"}',
dataType: 'json',
success: function(responseData, textStatus, jqXHR) {
var value = responseData.someKey;
},
error: function (responseData, textStatus, errorThrown) {
alert('POST failed.');
}
});
保持简单:
跨域: 使用crossDomain: true, 不应该刷新页面: 不,它不会刷新页面,因为当服务器发送回响应时将调用成功或错误异步回调。
示例脚本:
$.ajax({
type: "POST",
url: "http://www.yoururl.com/",
crossDomain: true,
data: 'param1=value1¶m2=value2',
success: function (data) {
// do something with server response data
},
error: function (err) {
// handle your error logic here
}
});
更新:在继续之前,每个人都应该阅读并理解html5rocks关于CORS的教程。它很容易理解,也很清楚。
如果您控制被post的服务器,只需通过在服务器上设置响应头来利用“跨源资源共享标准”。这个答案在本帖的其他答案中讨论过,但在我看来不是很清楚。
简而言之,下面是如何完成从from.com/1.html到to.com/postHere.php的跨域POST(以PHP为例)。注意:你只需要为NON OPTIONS请求设置Access-Control-Allow-Origin -这个例子总是为一个较小的代码片段设置所有的头部。
In postHere.php setup the following: switch ($_SERVER['HTTP_ORIGIN']) { case 'http://from.com': case 'https://from.com': header('Access-Control-Allow-Origin: '.$_SERVER['HTTP_ORIGIN']); header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS'); header('Access-Control-Max-Age: 1000'); header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With'); break; } This allows your script to make cross domain POST, GET and OPTIONS. This will become clear as you continue to read... Setup your cross domain POST from JS (jQuery example): $.ajax({ type: 'POST', url: 'https://to.com/postHere.php', crossDomain: true, data: '{"some":"json"}', dataType: 'json', success: function(responseData, textStatus, jqXHR) { var value = responseData.someKey; }, error: function (responseData, textStatus, errorThrown) { alert('POST failed.'); } });
When you do the POST in step 2, your browser will send a "OPTIONS" method to the server. This is a "sniff" by the browser to see if the server is cool with you POSTing to it. The server responds with an "Access-Control-Allow-Origin" telling the browser its OK to POST|GET|ORIGIN if request originated from "http://from.com" or "https://from.com". Since the server is OK with it, the browser will make a 2nd request (this time a POST). It is good practice to have your client set the content type it is sending - so you'll need to allow that as well.
MDN有一篇关于HTTP访问控制的文章,详细介绍了整个流程是如何工作的。根据他们的文档,它应该“在支持跨站XMLHttpRequest的浏览器中工作”。这有点误导,然而,因为我认为只有现代浏览器允许跨域POST。我只验证了这适用于safari,chrome,FF 3.6。
如果你这样做,请记住以下几点:
Your server will have to handle 2 requests per operation You will have to think about the security implications. Be careful before doing something like 'Access-Control-Allow-Origin: *' This wont work on mobile browsers. In my experience they do not allow cross domain POST at all. I've tested android, iPad, iPhone There is a pretty big bug in FF < 3.6 where if the server returns a non 400 response code AND there is a response body (validation errors for example), FF 3.6 wont get the response body. This is a huge pain in the ass, since you cant use good REST practices. See bug here (its filed under jQuery, but my guess is its a FF bug - seems to be fixed in FF4). Always return the headers above, not just on OPTION requests. FF needs it in the response from the POST.