我正在开发一个允许在小部件中使用用户编写的javascript的系统。为了确保安全,我计划在iframe中对这些小部件进行沙盒处理。当然,为了使沙箱有效,iframe必须具有与父文档不同的域。
我真的很想能够使用与此类似的代码动态生成iframe:
template = '<html><body><script>/* user code */</script></body></html>'
src = 'javascript: document.write("' + template + '")'
widget = $('<iframe>').attr('src', src)
$('#container').append(widget)
...然后将生成的iframe视为父窗口的跨域。这是可能的,如果是这样,它将如何完成?
答案 0 :(得分:3)
好吧,我想我得到了你需要的但是有点棘手。
您想创建一个<iframe>
并使用用户Javascript客户端填充它,但仍然将客户端沙箱化?
这是相当不标准的。通常,<iframe>
的内容是生成服务器端的。但是它就在这里。
首先是一些背景:文档无法访问不是来自同一域(包括子域)和端口的任何文档的内容。但是他们可以使用document.domain
属性更改自己的安全域。所以你需要做的就是减轻安全性,然后再将其重新收紧,以便用户脚本运行。
因此,您无法按照指定的方式执行此操作,因为如果您使用Javascript <iframe>
创建src
,则document.domain
将与父框架匹配。这意味着窗口小部件可以完全访问所有内容。
所以这就是你如何做到的:
home.example.com
和widgets.example.com
。widgets.example.com
上创建一个基本的HTML文件,并确保它调用此javascript:document.domain = "example.com";
document.domain
设置为相同的值。widgets.example.com
加载到其中。myFrame.contentWindow.foo = "template";
document.domain
切换回home.example.com
,以便<iframe>
无法再访问父框架最后一部分是棘手的部分。您不能只嵌入代码,因为如果它自动运行,它将在您更改主文档的域之前运行,这将是一个安全问题。因此,您需要将其设置为框架内的临时变量,然后以某种方式触发框架以使用该模板替换其自己的内容,但仅在锁定所有内容之后。最简单和最兼容的方法是在调整大小时触发它,然后只改变框架的宽度或高度。
现在,或者,如果小部件填充在服务器端:
widgets.example.com
home.example.com
但我认为你有理由在客户端做到这一点。
逻辑上的下一个主题:帧之间的通信和自动调整大小。但那些是另一天。
我是否回答了你的问题?我希望如此,因为这是很多打字,如果你投票并接受我的回答,我不会介意声望点! ;)