【问题标题】:Iframe Uploader Permissionsiframe 上传者权限
【发布时间】:2011-02-02 14:33:19
【问题描述】:

我在 iframe 中有这个文件上传器,但是当我将它嵌入到另一个网站时它不允许我,Firebug 显示此错误:

http://www.mywebsite.com> 拒绝从 http://www.myotherwebsite.com> 获取属性 Window.document。

到了这一行:

$('iframe', top.document).css('border', '1px green solid'); 

上传完成后,我正在尝试为 iframe 设置边框样式。

我看到其他问题,解决方案是制作服务器端代理,但我不知道如何制作代理以使其工作并允许执行 jQuery。

干杯。

已添加赏金。

【问题讨论】:

    标签: javascript jquery html iframe permission-denied


    【解决方案1】:

    服务器端代理可以帮助您解决这个问题。虽然浏览器只能使用同一域对其服务器进行 AJAX 调用,但服务器本身可以不受限制地调用任何其他服务器。

    假设您需要向 Yahoo 的 Weather API 发出 AJAX 请求。由于域策略相同,您无法从 www.example.com 向 www.yahoo.com 发出请求,因此解决方法是先调用您的服务器,然后让您的服务器向 Yahoo 发出请求。以下是执行此操作的代理示例:

    请求:http://www.example.com/weather.php?zip=97015

    <? // Yahoo Weather proxy
    
    $zip_code = $_REQUEST["zip"];
    
    // default to Portland, OR for testing
    if($zip_code == null || $zip_code == '')
        $zip_code = "97206";
    
    // delegate request to the other server, circumventing the same-domain policy.
    $request = "http://weather.yahooapis.com/forecastrss?p=".$zip_code;
    
    $response = file_get_contents($request);
    
    // Retrieve HTTP status code
    list($version,$status_code,$msg) = explode(' ',$http_response_header[0], 3);
    
    
    // Check the HTTP Status code
    switch($status_code) {
        case 200:
                // Success
                break;
        case 503:
                die('Your call to Yahoo Web Services failed and returned an HTTP status of 503. That means: Service unavailable. An internal problem prevented us from returning data to you.');
                break;
        case 403:
                die('Your call to Yahoo Web Services failed and returned an HTTP status of 403. That means: Forbidden. You do not have permission to access this resource, or are over your rate limit.');
                break;
        case 400:
                // You may want to fall through here and read the specific XML error
                die('Your call to Yahoo Web Services failed and returned an HTTP status of 400. That means:  Bad request. The parameters passed to the service did not match as expected. The exact error is returned in the XML response.');
                break;
        default:
                die('Your call to Yahoo Web Services returned an unexpected HTTP status of:' . $status_code);
    }
    
    
    echo $response;
    ?>
    

    现在,在您的情况下,您希望在文件上传完成后设置 iframe 的样式。一个简单的解决方案是轮询父文档的服务器并让代理轮询您的上传服务器,直到找到文件。找到文件后,可以使用响应调用更改 iframe 样式的 JQuery 代码。

    为了使代理概念起作用,您嵌入上传器的每个网站都需要部署自己的同域代理,该代理将检查您的上传站点是否存在文件,然后将该响应返回给客户。

    父文档也需要知道上传文件的名称。由于相同的域策略,您可能无法确定文件名,这在使用代理检查文件是否存在时提出了挑战。你怎么知道你在检查什么?

    【讨论】:

      【解决方案2】:

      您好,前几天我在试图找到一种方法在 iFrame 和使用名称加载它们的窗口之间来回交流时遇到了一篇文章。

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

      演示 - http://ajaxify.com/run/crossframe/duo/

      // site 1 code
      <iframe name="frame1" src="site2">
      

      假设您的第一个站点使用上面的 iFrame 在您的第二个站点中加载。第二个站点代码应添加此代码。

      //site 2 code
      $(something).load('url', function() {
          parent.frames["frame1"].css('border', '1px green solid');
      });
      

      我相信您也可以从站点 1 对 iFrame 进行函数调用:

      //site 1 code
      parent.frames["frame1"].functionName(variables);
      

      【讨论】:

      • 我猜你没有看演示。因为当您检查页面上的元素时,您会注意到与父页面交互的 iFrame 来自另一个域。
      【解决方案3】:

      服务器端代理

      apache配置

      LoadModule proxy_module modules/mod_proxy.so
      LoadModule proxy_http_module modules/mod_proxy_http.so
      
      ProxyRequests Off
      
      <Proxy *>
      Order deny,allow
      Allow from all
      </Proxy>
      
      ProxyPass /foo http://mywebsite.com/
      ProxyPassReverse /foo http://mywebsite.com/ 
      

      希望对你有帮助

      因此,如果您创建从 www.bar.com 到 www.bar.com/foo 的请求,则 apache 将传递给 www.mywebsite.com

      【讨论】:

      • 当我把它添加到我的.htaccess 的底部时,我得到了一个500 Internal Error。我确信您的解决方案会起作用,但只需要解决这个问题。
      【解决方案4】:

      我会反过来,从包含文档中删除边框,在 iframe 内添加一个假边框并更改它,跨域问题解决了。

      【讨论】:

      • 非常简单易行的解决方案。 +1
      【解决方案5】:

      框架不只是一些 HTML 内容吗?不能直接在iframe内的body标签周围加边框吗?

      如果您担心内容会因为额外的 2 个像素而移动,那么只需在开头放置一个相同尺寸的透明边框即可。

      【讨论】:

        【解决方案6】:

        你可以这样做:

        $("iframe").css('border', '1px green solid'); 上传完成

        我在这里创建了一个小提琴示例:

        http://jsfiddle.net/Mutant_Tractor/erAdS/8/

        【讨论】:

        • 这是不可能的,因为操作必须从 iframe 中触发。
        • 可以从 iframe 中激活脚本吗?如果是这样,您可以使用 JQuery 等将 CSS 边框应用于“整个页面”,从而使其出现在 iframe 的边缘周围......
        【解决方案7】:

        您可以轻松地将 easyXDM 应用于此问题 - 它甚至有一个 demo 如何使用响应数据进行跨域上传。

        this blog post我也解释了它背后的基础。

        【讨论】:

          【解决方案8】:

          如果您拥有所有网站,包括您的上传服务器和您将上传程序部署到的网站,那么也许一些简单的 DNS 技巧可以帮助您克服困难。

          • 假设您的上传服务器域是:upload.example.com
          • 假设您的服务器是www.example.com

          在上述情况下,您可以通过设置 document.domain 属性来启用跨站脚本:

          document.domain = "example.com";
          

          这允许 www.example.com 与 upload.example.com iframe 进行通信。

          假设您拥有这些网站,子域之间的通信能力可以帮助您在其他网络服务器之间进行通信。

          如果域不同,你会怎么做?

          假设如下:

          • upload.example.com 是您的上传服务器。
          • www.domain.com 是您的网站,它是包含上传者 iframe 的父文档。

          现在,我们再次假设您拥有这两个域名,或者至少可以访问设置。使用我们上面了解的关于在子域上启用跨站点脚本的知识,您可以使用一些 DNS 技巧来提供帮助。

          • 在您的 DNS 管理器中,为 upload.domain.com 创建一个 CNAME,并将该子域指向与 upload.example.com 相同的服务器。完成后,upload.example.comupload.domain.com 都指向同一个服务器和 PHP 应用程序。
          • www.domain.com中,嵌入upload.domain.com并设置document.domain="domain.com";
          • www.example.com 中,嵌入upload.example.com 并设置document.domain="example.com";

          您可以看到,在这两种情况下,您的网站域名都与上传者域名匹配,并且 document.domain 属性与域匹配。

          当您调用$('iframe', top.document).css('border', '1px green solid'); 时,您不会收到任何权限错误。

          总之,只要确保无论您在哪个网站中嵌入了该上传程序 iframe,您都已为该上传程序创建了与网站域匹配的 CNAME 别名,并且在两个上传程序中都设置了 document.domain 属性和网站。

          您可以使用 iframe 中的document.referrer 属性来动态确定父文档的上下文以确定域属性应设置为:

          // uploader file code
          
          // array split by period to get domain ["http://uploader", "example", "com/iframe/uploadFile", "php"]
          var domainSplit = document.referrer.split(".");  
          
          // the 2nd place in the array is the domain.  You may need to improve this for deeper subdomains
          document.domain = domainSplit[1];   
          

          注意:我假设您使用的是 Apache 和 PHP。如果是这样,您可以为所有 upload.XYZ.com 域创建 ServerAlias 条目。如果您使用的是另一台服务器,它们中的大多数都有一些设置 ServerAlias 的方法。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-05-20
            • 2011-03-29
            • 1970-01-01
            • 1970-01-01
            • 2011-12-03
            • 2022-08-03
            • 2017-08-09
            相关资源
            最近更新 更多