2

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

< http://www.mywebsite.com > 从 < http://www.myotherwebsite.com >获取属性 Window.document 的权限被拒绝。

这就是这一行:

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

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

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

干杯。

赏金添加。

4

8 回答 8

5

服务器端代理可以帮助您克服这个问题。虽然浏览器只能使用相同的域对其服务器进行 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 代码。

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

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

于 2011-02-07T08:08:05.667 回答
0

嗨,前几天我在试图找到一种在 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);
于 2011-02-02T20:54:01.437 回答
0

服务器端代理

阿帕奇配置

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

于 2011-02-06T14:07:56.917 回答
0

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

于 2011-02-06T14:40:55.763 回答
0

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

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

于 2011-02-06T14:44:28.020 回答
0

你可以这样做:

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

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

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

于 2011-02-06T16:45:09.603 回答
0

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

这篇博文中,我还解释了它背后的基础知识。

于 2011-02-06T23:24:29.403 回答
0

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

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

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

document.domain = "example.com";

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

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

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

让我们假设以下内容:

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

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

  • 在您的 DNS 管理器中,为该子域创建一个 CNAMEupload.domain.com并将其指向与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 属性.

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

// 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 的方法。

于 2011-02-07T08:31:46.067 回答