我创建以编程方式使用“数据” 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数据访问帧:text / html的;字符集= UTF-8,...从与URL为http帧:// ...请求访问该帧具有的“http”协议中,帧被访问具有“”的一个协议。 协议必须匹配。
下面是显示安全错误提琴: http://jsfiddle.net/bhGcw/4/
Firefox和Opera不会抛出此异常,并允许iframe的内容被改变。 似乎像的Webkit看到了数据URI空白协议,并且认为这是一个跨域冲突。
有没有办法解决?
这是一个有点晚了,怎么样,而不是使用数据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/
看来,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";
...
}
它看起来像铬按照以下错误报告比HTML5规范更加严格,至少包括:
- https://bugs.webkit.org/show_bug.cgi?id=17352
- https://code.google.com/p/chromium/issues/detail?id=58999
铬开发者似乎并不赞成放宽这一规则。 游民。
通过@jamie提出答案很适合装载HTML到iframe,并允许与内容文档后续程序化的交互。
XHTML也不是那么容易。
该srcdoc
属性似乎仅限于HTML,XHTML不会。
一个解决方法是使用一个Blob
URL允许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。