如何通过JavaScript发送跨域POST请求?

注释-它不应该刷新页面,然后我需要抓取并解析响应。


当前回答

我认为最好的方法是使用XMLHttpRequest(例如:jQuery中的$.ajax(), $.post())与跨起源资源共享polyfills之一https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills#wiki-CORS

其他回答

还有一件重要的事情要注意!! 在上面的例子中描述了如何使用

$.ajax({
    type     : 'POST',
    dataType : 'json', 
    url      : 'another-remote-server',
    ...
});

JQuery 1.6及以下版本在跨域XHR方面有一个bug。 根据Firebug,除了OPTIONS之外,没有其他请求发送。没有职位。在所有。

花了5个小时测试/调优我的代码。在远程服务器(脚本)上添加大量的头文件。没有任何效果。 但后来,我将JQuery lib更新到1.6.4,一切都很顺利。

我知道这是一个老问题,但我想分享我的方法。我使用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.');
}
});

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差异),获得响应,并返回您想要的任何内容。

高水平……您需要在服务器上设置cname,以便other-ser.your-server.com指向other-server.com。

您的页面动态地创建了一个不可见的iframe,它充当您到other-server.com的传输。然后,您必须通过JS从您的页面与other-server.com通信,并使用回调将数据返回到您的页面。

可能,但需要your-server.com和other-server.com的协调

如果您控制远程服务器,您可能应该使用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的响应,句号。否则会导致安全问题。