我正在使用“数据”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的空白协议,并将其视为跨域违规。
有什么方法吗?
答案 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>
有一个例子
答案 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。