以编程方式访问使用数据URI作为源的iframe

Vla*_*lin 9 javascript iframe webkit

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

<iframe id="myFrame" src='data:text/html;charset=utf-8,<!DOCTYPE html><html><head></head><body><h1>Hello.</h1></body></html>'></iframe>?
Run Code Online (Sandbox Code Playgroud)

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

var iframeDoc = document.getElementById('myFrame').contentWindow.document;
$(iframeDoc.body).find('h1').text('Changed');
Run Code Online (Sandbox Code Playgroud)

在Chrome和Safari中引发错误:

不安全的JavaScript尝试使用URL数据访问框架:text/html; charset = utf-8,...来自URL的URL http:// ...请求访问的框架具有"http"协议,正在访问的框架有一个''的协议.协议必须匹配.

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

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

有没有办法解决?

Jam*_*mie 7

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

<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>
Run Code Online (Sandbox Code Playgroud)

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


Vla*_*lin 6

似乎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";

    ...
}
Run Code Online (Sandbox Code Playgroud)

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

Chromium开发者似乎并不赞成放宽这条规则.游民.


小智 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);
Run Code Online (Sandbox Code Playgroud)

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