【问题标题】:Cross-subdomain Requests (GET, POST, ...) with Jquery and IFrame使用 Jquery 和 IFrame 的跨子域请求(GET、POST、...)
【发布时间】:2011-06-30 11:38:12
【问题描述】:

我正在尝试在我的主域 (http://foo.com) 和我的 API (http://api.foo.com) 之间开发请求。

为了绕过跨子域的限制,我在我的主页 (http.//foo.com/main.html) 上使用了一个 iframe,指向那里的 iframe.html 页面:scripts.api.foo .com。

(scripts.api.foo.com 和 foo.com 在同一个服务器上,api.foo.com 在另一个服务器上)

>iframe.html:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
       <head>
           <title>Iframe</title>
           <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
           <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
       </head>
       <body>
        <script type="text/javascript">
    document.domain = 'foo.com';
    function testIframe()
    {
        $.ajax({
                    url: "http://api.foo.com/utctime",
                    timeout: 7000,
                    complete: function(jqXHR, textStatus){
                        parent.alert(jqXHR.status);}
                });
    }
        </script>
       </body>
    </html>

>main.html:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
   <head>
       <title>Test</title>
       <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
       <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
   </head>
   <body>
    <script type="text/javascript">
document.domain = 'foo.com';
function test()
{
    pipeFrame.testIframe();
}
    </script>
    <iframe style="" src="http://scripts.api.foo.com/iframe.html" width="500" height="50" id="pipeFrame" name="pipeFrame"></iframe>
        <form>
           <p>
               <input type="button" value="Hop" onclick="test();" />
           </p>        
        </form>

   </body>
</html>

警报窗口始终包含“302”(重定向)(使用 Firefox 3.6/Chrome),“0”(使用 IE8)...虽然 Firebug 告诉我我的请求得到了“200 Ok”状态(无响应)...

我已尝试直接在 scripts.api.foo.com/iframe.html 上发起相同的请求,并获得相同的状态码。

我很沮丧,在网上搜索了一个明确的方法来实现跨子域,或者关于这些状态代码的解释...... 欢迎任何帮助。

非常感谢您的关注。 再见。

【问题讨论】:

    标签: jquery ajax iframe cross-domain subdomain


    【解决方案1】:

    不幸的是,跨域请求的规则最终也会阻止子域内的请求,即使从技术上讲它是同一台服务器。您可以通过代理运行或使用跨域 hack 来允许 $.ajax 调用运行。这里有一篇关于使用 iFrame 和跨域内容的非常好的文章

    http://softwareas.com/cross-domain-communication-with-iframes

    【讨论】:

    • 好吧,我已经阅读了这篇文章,但无法从他的理论中真正开发出解决方案……而且代理解决方案对我来说似乎很重。对于任何尝试使用 API 开发服务的人来说,跨子域是一个常见的问题......如何解决它没有达成共识?
    【解决方案2】:

    如果您只针对现代浏览器(例如,IE 8),您可以实现 OPTIONS 请求。现代浏览器会在尝试执行跨站点 GET 请求之前,向目标 (scripts.api.foo.com) 发送一个 OPTIONS 请求,询问是否可以在源 (foo.com) 上使用他们的脚本。然后,Web 服务器可以发送一个响应,上面写着:当然,你可以在 foo.com 上使用我的脚本。

    http://www.w3.org/TR/cors/

    【讨论】:

    • 感谢您提供信息,但我正在寻求更全球化的解决方案...使用 Iframe 似乎是一个不错的主意,但尽管我可以在我的主页 (foo.com/main.html) 和它的主页之间建立通信iframe(指向scripts.api.foo.com),从scripts.api.foo.com 发送的请求不会到达我在api.foo.com 上的服务器......我认为在(子)子域及其(子)域之间允许请求,但它在这里不起作用。 (是不是因为 api.foo.com 和 scripts.api.foo.com 不在同一个主机上?)感谢您的帮助,祝您有愉快的一天。
    • 您无法从主框架中的 iframe 获取信息,因为这正是跨站点脚本规则旨在防止的。您可以在 iframe 中加载 URL,是的,但是如果您能够从中读取,您还可以在 iframe 中加载银行 URL,并将用户的银行信息读回您的顶级框架。
    【解决方案3】:

    默认情况下,jQuery ajax 函数不适用于 IE 的等效于 XHR CORS,称为 XDR for XDomainRequest... 只需在您的第一个 ajax 调用之前添加它,它可能适用于您的情况...

    $(document).ready(function(e) {
        // CORS + XDR for Internet Explorer
        if ('XDomainRequest' in window&&window.XDomainRequest!==null)
        {jQuery.ajaxSettings.xhr=function(){try{return new XDomainRequest();}
        catch(e){}}; jQuery.support.cors = true;}
    });
    

    【讨论】:

      【解决方案4】:

      只是把它扔在那里,但为什么不是 JSONP?

          $.ajax({
              url: "http://api.foo.com/utctime",
              type: "POST",
              dataType: "jsonp",
              jsonp: "callback",
              timeout: 7000,
          })
          .success(function (result) {
              //do something with the result
          })
          .error(function (err) {
              //do something if err;d
          });
      

      【讨论】:

        猜你喜欢
        • 2011-08-19
        • 2010-12-07
        • 2010-11-13
        • 1970-01-01
        • 2014-02-09
        • 2015-01-17
        • 1970-01-01
        • 2011-11-30
        相关资源
        最近更新 更多