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

时间:2013-01-04 00:37:13

标签: 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>​

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

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

在Chrome和Safari中引发错误:

  

不安全的JavaScript尝试使用URL访问框架   data:text / html; charset = utf-8,...来自带有URL http:// ...的框架   请求访问的帧具有“http”协议,帧是   access具有''的协议。协议必须匹配。

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

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

有什么方法吗?

3 个答案:

答案 0 :(得分: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>

http://jsfiddle.net/ff3bF/

有一个例子

答案 1 :(得分:6)

Webkit似乎在domain checking code中进行了简单的字符串比较:

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 devs似乎并不赞成放宽这条规则。长号。

答案 2 :(得分:4)

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

XHTML并不那么容易。

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

解决方法是使用Blob网址,该网址允许指定content-type

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。