提交跨域ajax POST请求

我发誓我曾经看过一篇关于这个的文章,但找不到它……

如何在另一个域上执行POST类型的jQuery ajax请求? 必须在没有代理的情况下完成。 这可能吗?

是的,你可以发布你想要的所有内容,甚至是$.post()可以……但是你不会得到回复。

这工作,其他域获得POST:

 $.post("http://othersite.com/somePage.php", { thing: "value" }, function(data) { //data will always be null }); 

但是,由于同源策略 ,上面示例中的响应data将为null。

我尝试过的所有选项:

1)PORK: http : //www.schizofreend.nl/Pork.Iframe/Examples/创建一个iframe并在那里提交post,然后读取响应。 每个请求仍需要相同的基本域(即www.foo.com可以从www2.foo.com请求数据,但不能从www.google.com请求数据)。 还需要你摆弄document.domain属性,这会导致不良副作用。 并且在所有主流浏览器中存在一个普遍存在的问题,即如果动态编写任何iframe,则重新加载页面基本上会对页面上所有iframe的缓存内容进行洗牌。 您的回复数据会显示在广告所在的框中。

2)flxhr: http ://flxhr.flensed.com/甚至可以用来掩盖jQuery的内置ajax,所以你甚至都没有注意到它。 虽然需要闪存,所以iPhone出局了

3)jsonp:如果您发布了大量数据,则无效。 嘘。

4)chunked jsonp:当你的jsonp请求太大时,将查询字符串分解为可管理的块并发送多个get请求。 在服务器上重建它们。 这很有用,但如果您在服务器之间对用户进行负载平衡,则会出现故障。

5)CORS: http : //www.w3.org/TR/cors/在旧版浏览器中不起作用(IE7,IE6,Firefox 2等)

所以我们目前做以下算法:

  • 如果请求足够小,请使用JSONP
  • 如果不够小,但用户有闪光灯,请使用FlXHR
  • 否则使用分块JSONP

花一个下午写下来,你就可以好好利用它了。 将CORS添加到我们的算法可能有助于更快的iPhone支持。

如果您可以控制在其他域上运行的代码,只需让它在响应中返回适当的Access-Control-Allow-Origin标头。 另请参阅MDC上的HTTP Access-Control

如果您想要点火并忘记POST而不关心响应,那么只需将表单提交给隐藏的iframe即可。 这需要Transitional Doctype。

 

如果要解析响应,则使用代理(如果唯一的实际选项)。

如果你绝望 ,并控制远程站点,那么你可以:

  1. 提交上述表格
  2. 在响应中设置一个cookie(在iframe可能导致cookie被视为’第三方’之前可能被阻止(即可能是广告跟踪)。
  3. 等待足够长的时间让回复回来
  4. 动态生成脚本元素,其中src指向远程站点
  5. 在响应中使用JSON-P并利用先前存储在cookie中的数据

这种方法受到竞争条件的影响并且通常很难看。 通过当前域提供数据是一种更好的方法。

如果您需要知道POST成功,并且无法控制远程服务器:

  $.ajax({ type:"POST", url:"http://www.somesite.com/submit", data:'firstname=test&lastname=person&email=test@test.com', complete: function(response){ if(response.status == 0 && response.statusText == "success") { /* CORS POST was successful */ } else { /* Show error message */ } } }); 

如果提交有问题,那么response.statusText应该等于"error"

注意:某些远程服务器将发送HTTP标头Access-Control-Allow-Origin: * ,这将导致200 OK HTTP状态代码响应。 在这种情况下,ajax将执行success处理程序,并且不需要此方法。 要查看响应,只需执行console.log(JSON.stringify(response)); 或使用FireBug的’Net’面板。