如何通过JavaScript发送跨域POST请求?
注释-它不应该刷新页面,然后我需要抓取并解析响应。
如何通过JavaScript发送跨域POST请求?
注释-它不应该刷新页面,然后我需要抓取并解析响应。
当前回答
我知道这是一个老问题,但我想分享我的方法。我使用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.');
}
});
其他回答
这是一个老问题,但一些新技术可能会帮助人们解决这个问题。
如果你有对其他服务器的管理访问权限,那么你可以使用开源Forge项目来完成你的跨域POST。Forge提供了一个跨域JavaScript XmlHttpRequest包装器,它利用了Flash的原始套接字API。POST甚至可以通过TLS完成。
您需要对您要发布的服务器进行管理访问的原因是,您必须提供一个跨域策略,允许从您的域进行访问。
http://github.com/digitalbazaar/forge
如果您可以访问所有相关的服务器,请在另一个域请求的页面的回复标题中放入以下内容:
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;
}
这可能会产生安全问题,您应该确保采取了适当的措施来验证请求。
Create two hidden iframes (add "display: none;" to the css style). Make your second iframe point to something on your own domain. Create a hidden form, set its method to "post" with target = your first iframe, and optionally set enctype to "multipart/form-data" (I'm thinking you want to do POST because you want to send multipart data like pictures?) When ready, make the form submit() the POST. If you can get the other domain to return javascript that will do Cross-Domain Communication With Iframes (http://softwareas.com/cross-domain-communication-with-iframes) then you are in luck, and you can capture the response as well.
当然,如果您想使用您的服务器作为代理,您可以避免所有这些。只需将表单提交到您自己的服务器,该服务器将把请求代理到另一个服务器(假设另一个服务器没有设置为注意到IP差异),获得响应,并返回您想要的任何内容。
如果您控制远程服务器,您可能应该使用CORS,如回答中所述;它在IE8及以上版本,以及FF、GC和Safari的所有最新版本中都得到支持。(但是在IE8和ie9中,CORS不允许你在请求中发送cookie。)
所以,如果你不控制远程服务器,或者你必须支持IE7,或者你需要cookie并且你必须支持IE8/9,你可能会想要使用iframe技术。
创建一个名称唯一的iframe。(iframes为整个浏览器使用全局名称空间,因此请选择其他网站不会使用的名称。) 构造一个带有隐藏输入的表单,以iframe为目标。 提交表单。
下面是示例代码;我在IE6、IE7、IE8、IE9、FF4、GC11和S5上进行了测试。
function crossDomainPost() {
// Add the iframe with a unique name
var iframe = document.createElement("iframe");
var uniqueString = "CHANGE_THIS_TO_SOME_UNIQUE_STRING";
document.body.appendChild(iframe);
iframe.style.display = "none";
iframe.contentWindow.name = uniqueString;
// construct a form with hidden inputs, targeting the iframe
var form = document.createElement("form");
form.target = uniqueString;
form.action = "http://INSERT_YOUR_URL_HERE";
form.method = "POST";
// repeat for each parameter
var input = document.createElement("input");
input.type = "hidden";
input.name = "INSERT_YOUR_PARAMETER_NAME_HERE";
input.value = "INSERT_YOUR_PARAMETER_VALUE_HERE";
form.appendChild(input);
document.body.appendChild(form);
form.submit();
}
小心!您不能直接读取POST的响应,因为iframe存在于一个单独的域中。帧不允许与来自不同域的帧相互通信;这是同源策略。
如果你控制远程服务器,但你不能使用CORS(例如,因为你在IE8/IE9上,你需要使用cookie),有一些方法可以绕过同源策略,例如使用window。postMessage和/或允许你在旧浏览器中发送跨域跨帧消息的库之一:
汽门 XSSInterface EasyXDM jQuery PostMessage插件
如果不控制远程服务器,就不能读取POST的响应,句号。否则会导致安全问题。
我认为最好的方法是使用XMLHttpRequest(例如:jQuery中的$.ajax(), $.post())与跨起源资源共享polyfills之一https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills#wiki-CORS