如何在iframe中获取javascript来修改父文档?

时间:2009-08-16 07:39:51

标签: javascript iframe

所以我有两个文件dA和dB分别托管在两个不同的服务器sA和sB上。

文档dA有一些JS打开一个iframe src的文档dB,上面有一个表单。当文档dB中的表单提交给服务器sB上的表单处理程序时,我希望页面dA上的iframe关闭。

我希望这很清楚。有没有办法做到这一点?

谢谢!

-Mala

更新:除了通过插入的javascript

,我无法控制dA或sA

8 个答案:

答案 0 :(得分:3)

由于浏览器/ JavaScript安全沙箱策略,这是不可能的。话虽这么说,有可能超出这些限制,但有点hackery。有多种方法,一些涉及Flash。

如果可能的话,我建议不要这样做,但如果必须,我会建议这里提到的DNS方法:

http://www.alexpooley.com/2007/08/07/how-to-cross-domain-javascript/

主要摘录:

  

说域D想要   连接到域E.简而言之,   诀窍是使用DNS指向一个   D,D_s的子域到E的服务器。   在这样做时,D_s接受了   E的特征,同时也是   可以访问D.

答案 1 :(得分:3)

如果你只想让顶级关闭,你可以这样打电话:

window.top.location = "http://www.example.com/dC.html";

这将关闭dA并将用户发送到dC.htmldC.html可以在onload处理程序中运行要运行的JS(例如,关闭窗口)。

答案 2 :(得分:2)

假设我创建了一个页面A,它位于覆盖整个页面的框架上。 让A链接到yourbank.com,然后点击该链接。现在,如果我可以使用javascript来修改框架(银行网站)的内容,我将能够非常轻松地读取您正在使用的密码并将其存储在cookie中,将其发送到我的服务器等。

这就是您无法修改其内容不是来自同一域的另一帧内容的原因。但是,如果它们来自同一个域,您应该能够根据需要对其进行修改(两个页面都必须在您的服务器上)。

您应该可以使用以下代码访问iframe:

window["iframe_name"].document.body

答案 3 :(得分:2)

其他人解释了安全问题。但问题是合法的,有用例,在某些情况下可以做你想做的事。

W3C在名为document的{​​{1}}上定义了一个属性,用于检查安全权限。这两个文档可以协同操作此属性,因此在某些情况下它们可以相互访问。

管理文件是DOM Level 1 Spec。看看the description of document。如您所见,此属性在那里定义并且......它是只读的。实际上,所有浏览器都允许修改它:

修改不能是任意的。通常只允许超级域名。这意味着只要具有共同的超级域,您就可以使不同服务器提供的两个文档相互访问。

因此,如果您想要两个页面进行通信,则需要添加一个小的单行,应该在页面加载时运行。这样的事情可以解决问题:

domain

现在,您可以从不同的子域服务它们,而不会失去其可访问性。

显然你应该留意时间问题。如果您建立某种通知协议,则可以避免它们。例如,一个页面(主服务器)设置其域,并加载另一个页面(服务器)。当服务器运行时,它会更改其域并访问主服务器,从而触发某些功能。

答案 4 :(得分:0)

这样做的机制将能够进行跨站脚本攻击(因为除了删除良好的页面内容之外,您还可以做更多的事情)。

安全方法仅限于iframe文档清空/隐藏本身,但如果包含它的iframe是固定大小,则最终会在页面上留下空白点。

答案 5 :(得分:0)

如果您无法控制dA或Sa,则由于浏览器安全限制,这是不可能的。即使Flash方法也需要访问两个服务器。

答案 6 :(得分:0)

这有点令人费解,但可能比直接的XSS解决方案更合理:

除了将javascript写入文档A之外,您无法控制服务器A.但是您在文档A中打开了iframe,这表明您只能对文档A进行写入访问。这有点令人困惑。你是在写文件A或以某种方式注入它吗?

无论哪种方式,这都是我梦寐以求的。如果您无权访问托管具有iframe的页面的服务器,则无法使用。

用户点击iframe中的表单上的提交。该表单一旦完成,很可能会在托管该表单的服务器上进行更改。因此,您在文档A上有一个AJAX函数,它要求服务器端脚本检查表单是否已提交。如果有,脚本会向AJAX函数返回一个“提交”值,触发另一个js函数来关闭iframe。

以上需要做一些事情:

  • iframe需要位于服务器上托管的页面上,您可以在其中编写其他服务器端脚本(这可以避免跨域问题,因为理论上AJAX指向同一目录)

  • iframe中的服务器必须有一些可以请求的网址,这会返回某种形式已提交的确认。

  • “check-for-submitted”脚本需要知道上述网址以及加载网址时要查找的内容。

如果你有上述所有内容,ajax函数调用服务器脚本,服务器脚本使用cURL去反映表单是否完成的URL,服务器脚本查找“表单已提交“指标,并根据它找到的内容,返回”未提交“或”已提交“给ajax函数的答案。

例如,表格可能是用户注册的。如果您的外部文档知道将在表单中输入的用户名,则服务器端脚本可以转到http://example.org/username,如果出现“未找到用户”,则表示该表单尚未提交。

超出上述示例可能的任何内容可能超出了安全可靠的范围。虽然在用户提交iframe时自动关闭会非常方便,但请考虑我向您发送了一封电子邮件,说明您的银行帐户需要查看。该电子邮件中包含指向我所创建网页的链接,该网页设置了银行网站的iframe,以填充我页面的整个可见部分。您正常登录,因为您非常信任。如果我可以访问您在页面上点击提交的事实,那意味着我也可以访问您提交的内容,或者至少可以访问iframe重定向到的URL(可能包含会话ID或各种类型的会话ID)银行不应包含在URL中的其他数据。)

我并不是说听起来很有说服力。您应该考虑一下,为了了解一个事件,您经常可以访问您不应该拥有的其他数据。

我认为对您的问题稍微不太优雅的解决方案是在iframe上方有一个链接,表示“完成”或“关闭”,当用户完成表单时会杀死iframe。这不仅可以在用户提交表单时关闭iframe,还可以让他们有机会说“哎呀!我还是不想填写这张表格。没关系!”现在使用您想要的自动解决方案,除非用户点击提交,否则无法摆脱iframe。

答案 7 :(得分:0)

谢谢大家的回答。我找到了一个有效的解决方案:

在我的服务器上,我告诉表单重定向到创建iframe的网址。 在包含iframe的网站上,我添加了一个setInterval函数来轮询iframe的当前位置。

由于JS沙盒,当url是外来的(即在我的表单提交之前),此民意调查不起作用。但是,一旦url是本地的(即与调用页面的url相同),url是可读的,并且该函数关闭iframe。一旦iframe被重定向,这就行了,我甚至不需要等待额外的页面加载。

非常感谢格雷格帮助我:)