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

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


当前回答

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

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

其他回答

保持简单:

跨域: 使用crossDomain: true, 不应该刷新页面: 不,它不会刷新页面,因为当服务器发送回响应时将调用成功或错误异步回调。


示例脚本:

$.ajax({
        type: "POST",
        url: "http://www.yoururl.com/",
        crossDomain: true,
        data: 'param1=value1&param2=value2',
        success: function (data) {
            // do something with server response data
        },
        error: function (err) {
            // handle your error logic here
        }
    });

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

创建一个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,隐藏和绝对定位。不确定跨站点发布将被浏览器允许,但如果是这样,这是如何做到的。

更新:在继续之前,每个人都应该阅读并理解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.

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

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

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

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