【问题标题】:Submit cross domain ajax POST request提交跨域ajax POST请求
【发布时间】:2010-10-06 22:14:05
【问题描述】:

我发誓我曾经看过一篇关于此的文章,但找不到...

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

【问题讨论】:

  • @David @Nick true,我撤回我的评论 :)

标签: javascript jquery


【解决方案1】:

是的,您可以发布任何您想要的内容,即使 $.post() 有效……但您不会得到回复。

这行得通,其他域获得 POST:

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

但由于same-origin policy,上述示例中的data 响应将为空。

【讨论】:

  • 如果我使用 $.post,请求会显示在 firebug 中吗?我现在正在尝试,但什么也没看到。
  • @Louis - request 是的,response 不,它反映了您的代码将看到的内容......由于标准操作程序。
  • @Louis - 顺便说一句,你要发送什么?它是 GET 可以处理的吗?因为您可以使用 JSONP 请求在 GET 请求上传递其他参数...您可以看到的响应。不过,其他域必须支持这一点。
  • 抱歉延迟回复您,我做了一些测试,但似乎无法使其正常工作。 Javascript 将发布但不发送任何字段。我在这里上传了一个简化的示例:loui5.com/tmp/js_xss_post。我还可以补充一下,请求没有出现在 firebug 中,但我得到了(页面通过电子邮件发送给我)。
  • @NickCraver 这可能是一个旧帖子,但这不意味着如果即使您无法获得响应也可以将帖子请求发送到服务器,CSRF 是可能的,更像是火灾并忘记攻击?
【解决方案2】:

我尝试过的所有选项:

1) PORK: http://www.schizofreend.nl/Pork.Iframe/Examples/ 创建一个 iframe 并在那里提交帖子,然后读取响应。每个仍然需要相同的基域 请求(即 www.foo.com 可以请求 来自 www2.foo.com 的数据,但不是来自 www.google.com)。还需要你 摆弄document.domain 财产,这导致不利的一面 效果。在所有主要浏览器中都存在一个普遍的问题,如果其中任何一个是动态写入的,那么重新加载页面基本上会打乱页面上所有 iframe 的缓存内容。您的响应数据将显示在广告应该出现的框中。

2) flxhr: http://flxhr.flensed.com/ 甚至可以用来屏蔽 jQuery 的内置 ajax,所以你甚至不会注意到它。不过需要闪光灯,所以 iPhone 已经过时了

3) jsonp:如果您要发布大量数据,则不起作用。嘘。

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

5) CORS:http://www.w3.org/TR/cors/ 不适用于旧版浏览器(IE7、IE6、Firefox 2 等)

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

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

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

    • 目前对 ACAO 的浏览器支持相当有限。我不想在野外使用它。
    • @David:OP 只是询问是否可以不使用代理。我只是这么回答的。 OP发誓他看到了一篇文章。我想象它是关于Access-Control 标题。无论如何,浏览器支持存在于几乎所有小于 1 年的现代浏览器/更新中。
    【解决方案4】:

    如果您想要火而忘记了您不关心响应的 POST,那么只需将表单提交到隐藏的 iframe。这需要一个过渡文档类型。

    <form method="POST" action="http://example.com/" target="name_of_iframe">
    

    如果你想解析响应,那么使用代理是唯一真正的选择。

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

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

    这种方法会受到竞争条件的影响,而且通常很难看。通过当前域代理数据是一种非常更好的方法。

    【讨论】:

    • 尽管这不是必需的,但任何 jQuery POST-ing AJAX 函数都可以更简单地完成同样的事情。
    • 这些函数是,AFAIK,只是围绕生成 iframe 的高级包装器。了解库在做什么总是很有用的,因此您可以了解限制并在出现问题时进行处理。
    • @David - 他们根本不使用&lt;iframe&gt;,他们使用的是XmlHttpRequest()POST 没有被阻止,只有得到响应。
    • @David - 老实说,我很好奇为 jQuery 在下面所做的事情生成 &lt;iframe&gt; 的想法是从哪里来的,是否有文章说这个,或者一些文档给人留下了这样的印象?
    • 对此进行调查。我还记得向 iframe 添加 onload 函数以与父级对话以提供内容的能力。你从来没有尝试过。
    【解决方案5】:

    如果您需要知道 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 的“网络”面板。

    【讨论】:

      猜你喜欢
      • 2012-04-15
      • 2015-01-28
      • 2012-05-10
      • 2013-03-06
      • 1970-01-01
      • 1970-01-01
      • 2013-01-05
      • 1970-01-01
      相关资源
      最近更新 更多