10

我正在使用“数据”URI 以编程方式创建 iframe:

<iframe id="myFrame" src='data:text/html;charset=utf-8,<!DOCTYPE html><html><head></head><body><h1>Hello.</h1></body></html>'></iframe>​

此框架加载正常,但似乎以编程方式使用 iframe 会命中跨域安全检查。

var iframeDoc = document.getElementById('myFrame').contentWindow.document;
$(iframeDoc.body).find('h1').text('Changed');

在 Chrome 和 Safari 中引发错误:

不安全的 JavaScript 尝试使用 URL 访问框架 data:text/html;charset=utf-8,... from frame with URL http://... 请求访问的框架具有“http”协议,被访问的框架有一个协议''。协议必须匹配。

这是一个显示安全错误的小提琴:http: //jsfiddle.net/bhGcw/4/

Firefox 和 Opera 不会抛出此异常并允许更改 iframe 内容。似乎 Webkit 看到了数据 URI 的空白协议,并将其视为跨域违规。

有没有办法解决?

4

3 回答 3

8

有点晚了,不如不使用数据 URL,而是使用 HTML5 属性 srcdoc。

<iframe id="iframe" srcdoc='<html><body><h1>Hello!</h1></body></html>'></iframe>
<script type="text/javascript">
    $(function(){
        $($("iframe")[0].contentWindow.document).find("h1").text("Modified from the parent window!");
    });
</script>

在http://jsfiddle.net/ff3bF/有一个例子

于 2014-03-30T19:21:54.177 回答
7

似乎 Webkit 在其域检查代码中进行了简单的字符串比较:

String DOMWindow::crossDomainAccessErrorMessage(DOMWindow* activeWindow)
{
    ...

    SecurityOrigin* activeOrigin = activeWindow->document()->securityOrigin();
    SecurityOrigin* targetOrigin = document()->securityOrigin();
    if (targetOrigin->protocol() != activeOrigin->protocol())
        return message + " The frame requesting access has a protocol of '" + activeOrigin->protocol() + "', the frame being accessed has a protocol of '" + targetOrigin->protocol() + "'. Protocols must match.\n";

    ...
}

看起来 Chromium 比 HTML5 规范更严格,至少根据以下错误报告:

Chromium 开发人员似乎不赞成放宽此规则。真可惜。

于 2013-01-04T00:52:30.933 回答
6

@jamie 提出的答案非常适合将 HTML 加载到 iframe 中并允许随后与内容文档进行编程交互。

XHTML 并不那么容易。

srcdoc属性似乎仅限于 HTML,而不是 XHTML。

一种解决方法是使用Blob允许content-type指定的 URL。

var documentSource = '<?xml version="1.0" encoding="UTF-8"?>\n<html xmlns="http://www.w3.org/1999/xhtml">\n<head>...';
var blob = new Blob([documentSource], { type: "application/xhtml+xml" });
iframe.src = URL.createObjectURL(blob);

这种技术至少适用于 Chrome、Firefox 和 Safari。

于 2014-09-08T04:11:21.190 回答