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

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


当前回答

应该可以用YQL自定义表+ JS XHR,看看: http://developer.yahoo.com/yql/guide/index.html

我用它来做一些客户端(js) html抓取,工作很好 (我有一个完整的音频播放器,搜索互联网/播放列表/歌词/最后调频信息,所有客户端js + YQL)

其他回答

如果您可以访问所有相关的服务器,请在另一个域请求的页面的回复标题中放入以下内容:

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;
}

这可能会产生安全问题,您应该确保采取了适当的措施来验证请求。

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

如果你可以访问跨域服务器,并且不想在服务器端做任何代码更改,你可以使用一个名为“xdomain”的库。

工作原理:

步骤1: 服务器1:包含xdomain库,并将跨域配置为从域:

<script src="js/xdomain.min.js" slave="https://crossdomain_server/proxy.html"></script>

步骤2: 在跨域服务器上,创建一个proxy.html文件,并将服务器1作为主服务器:

proxy.html:
<!DOCTYPE HTML>
<script src="js/xdomain.min.js"></script>
<script>
  xdomain.masters({
    "https://server1" : '*'
  });
</script>

步骤3:

现在,您可以从server1对proxy.html作为端点进行AJAX调用。这是绕过CORS请求。图书馆内部使用iframe解决方案,它与凭证和所有可能的方法一起工作:GET, POST等。

查询ajax代码:

$.ajax({
        url: 'https://crossdomain_server/proxy.html',
        type: "POST",
        data: JSON.stringify(_data),
        dataType: "json",
        contentType: "application/json; charset=utf-8"
    })
    .done(_success)
    .fail(_failed)

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

CORS是为你准备的。 CORS是“跨域资源共享”,是一种发送跨域请求的方式。现在XMLHttpRequest2和Fetch API都支持CORS,它可以发送POST和GET请求

但它也有局限性。服务器需要指定Access-Control-Allow-Origin,不能设置为“*”。

如果你想要任何origin都可以发送请求给你,你需要JSONP(也需要设置Access-Control-Allow-Origin,但可以是'*')

对于很多请求方式,如果你不知道如何选择,我认为你需要一个完整的功能组件来做到这一点。让我介绍一个简单的组件https://github.com/Joker-Jelly/catta


如果你正在使用现代浏览器(> IE9, Chrome, FF, Edge等),非常建议你使用一个简单但美丽的组件https://github.com/Joker-Jelly/catta.It没有依赖,小于3KB,它支持Fetch, AJAX和JSONP与相同致命的示例语法和选项。

catta('./data/simple.json').then(function (res) {
  console.log(res);
});

它还支持所有方式导入到您的项目,如ES6模块,CommonJS,甚至HTML中的<script>。