如何通过JavaScript发送跨域POST请求?
注释-它不应该刷新页面,然后我需要抓取并解析响应。
如何通过JavaScript发送跨域POST请求?
注释-它不应该刷新页面,然后我需要抓取并解析响应。
当前回答
这是一个老问题,但一些新技术可能会帮助人们解决这个问题。
如果你有对其他服务器的管理访问权限,那么你可以使用开源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;
}
这可能会产生安全问题,您应该确保采取了适当的措施来验证请求。
创建一个iFrame, 在里面放入一个隐藏输入的表单, 将表单的动作设置为URL, 向文档中添加iframe 提交表格
伪代码
var ifr = document.createElement('iframe');
var frm = document.createElement('form');
frm.setAttribute("action", "yoururl");
frm.setAttribute("method", "post");
// create hidden inputs, add them
// not shown, but similar (create, setAttribute, appendChild)
ifr.appendChild(frm);
document.body.appendChild(ifr);
frm.submit();
你可能想样式iframe,隐藏和绝对定位。不确定跨站点发布将被浏览器允许,但如果是这样,这是如何做到的。
我知道这是一个老问题,但我想分享我的方法。我使用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.');
}
});
还有一件重要的事情要注意!! 在上面的例子中描述了如何使用
$.ajax({
type : 'POST',
dataType : 'json',
url : 'another-remote-server',
...
});
JQuery 1.6及以下版本在跨域XHR方面有一个bug。 根据Firebug,除了OPTIONS之外,没有其他请求发送。没有职位。在所有。
花了5个小时测试/调优我的代码。在远程服务器(脚本)上添加大量的头文件。没有任何效果。 但后来,我将JQuery lib更新到1.6.4,一切都很顺利。
如果您控制远程服务器,您可能应该使用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的响应,句号。否则会导致安全问题。