2011-06-16 193 views
1

我正在开发一个允许在小部件中使用用户编写的JavaScript的系统。为了保持安全,我打算将这些小部件在iframe中进行沙箱处理。当然,为了使沙箱有效,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被视为从父窗口跨域。这是否可能,如果是的话,它将如何完成?

回答

3

好吧,我想我得到你需要的东西,但这有点棘手。 你想创建一个并用用户的Javascript客户端填充它,但仍然有客户端沙箱?

这是相当不标准的。服务器端通常生成的内容。但是在这里。

首先是一些背景知识:文档不能访问不是来自同一个域(包括子域)和端口的任何文档的内容。但他们可以使用document.domain属性更改自己的安全域。因此,您需要做的是减轻安全性,然后再次将其恢复以供用户脚本运行。

所以你不能按照你指定的方式来做,因为如果你使用Javascript src创建,document.domain将匹配父框架。这意味着小部件将完全访问所有内容。

因此,这里是你如何能做到这一点:

  1. 设置主域的两个子域。我们称它们为home.example.comwidgets.example.com
  2. 创建于widgets.example.com一个基本的HTML文件,并确保它调用此javascript:document.domain = "example.com";
  3. 现在创建您的网页,将包含所有这些小部件。将其设置为document.domain为相同的值。
  4. 创建所有的iframe将您的基本HTML页面从widgets.example.com加载到它。
  5. 在包含用户模板的框架内设置一个变量。例如:myFrame.contentWindow.foo = "template";
  6. 切换主窗口上的document.domainhome.example.com使得旨意无法再访问父框架
  7. 触发的框架模板替换

这最后一部分是棘手的部分。您不能只是嵌入代码,因为如果它自动运行,它将会运行,然后您可以将主文档的域更改回来,这将是一个安全问题。因此,您需要将其设置为框架内的临时变量,然后以某种方式触发框架以使用该模板替换其自己的内容,但只能在所有内容都被锁定后才能使用该模板。最简单和最兼容的方法是在调整大小后触发它,然后更改帧的宽度或高度。

现在,或者,如果小部件被填充服务器端:

  1. 主机部件上widgets.example.com
  2. 含有小部件主机页面上home.example.com
  3. 完成

但我认为你有理由在客户端做所有事情。

逻辑下一个主题:帧之间的通信和自动调整大小。但那些是另一天。

我回答了您的问题吗?我希望如此,因为这是很多打字,如果你投票并接受我的答案,我不会介意声望点! ;)

+0

你真的不应该要求人们upvote/accept。这是这个网站的基础,要求它会让很多人完全相反!尽管如此,+1为伟大的答案:)。 – gnur 2011-06-16 07:23:52

+1

@gnur对不起,感谢您的+1。我注意到@ jpadvo的最后一个问题是在十月份,他从未对任何答案进行评论或评分,所以这只是一个友好的捅捅。 – 2011-06-16 12:01:27

+0

我现在只有11个声望,所以我还没有放弃。当我可以的时候,我一定会给你一个。我会测试它,如果它有效,我也会接受它。 :) – jpadvo 2011-06-16 17:23:40