跨域iframe获取DOM内容

100

我有一个用于跨域站点的iframe。 我想读取iframe的DOM,因为使用检查器,我甚至可以修改iframe的DOM,所以我相信这是可能的。 然而,我尝试阅读它的每种方式都会遇到同源策略。 我想要的只是从iframe加载到本地DOM中的内容。 我认为这应该很简单,比如$(document.body).find('iframe').html(),但是它返回了空字符串。

我真的希望有一种方法可以做到这一点,因为我过去几天的工作都是建立在这个基础上的。

谢谢


4
可以的,你可以做到这一点 - 参见 https://dev59.com/L2Up5IYBdhLWcg3w3KTe#17262334。 - Stefan
5个回答

103
你做不到。由于XSS保护,JavaScript无法读取跨站点的内容。任何主要浏览器都不会允许这样做。很抱歉,但这是一个设计缺陷,你应该放弃这个想法。
编辑说明:
请注意,如果您可以编辑嵌入iframe中的网站,则可以使用postMessage(另请参见浏览器兼容性)。

14
如果你的意思是“设计(流程)缺陷”,那么不,这并不是一个缺陷,这是为了安全而实施的。 - Ibu
3
那我误解了。 - Ibu
1
最终,我并不需要使用iframe来完成我的任务。 - D-Nice
2
参考资料,跨域同源策略意味着主机名、端口和协议必须完全相同 - https://en.wikipedia.org/wiki/Same-origin_policy(例如,app1.example.com 和 app2.example.com 是不同的;example.com 和 www.example.com 也是不同的) - Curtis Yallop
3
注意:您可以使用window.postMessage在iframe和主窗口之间进行通信。 - Curtis Yallop
显示剩余2条评论

26

有一种简单的方法。

  1. 创建一个iframe,在其源代码中设置类似于“http://your-domain.com/index.php?url=http://the-site-you-want-to-get.com/unicorn”的内容。

  2. 接下来,你只需使用$_GET获取此URL,并使用file_get_contents($_GET['url'])显示其内容。

这样,你将获得一个与你的域名相同的iframe,然后就可以使用$("iframe").contents().find("body")来操作其内容。


2
请您能否详细解释一下。非常感谢! - bfhaha
5
很抱歉晚了,我没有注意到。
  1. 创建一个 PHP 页面,可以通过 GET 参数显示所需页面的内容。
content.php <?php echo file_get_contents($_GET['url']); ?>
  1. 然后,在您的主页面中添加一个 iframe,将加载此页面。 <iframe src="content.php?url=http://google.com">
  2. 它将在 iframe 中显示所需的页面。 Content.php 来自您的域,因此您可以使用 JS 操纵 iframe 内容,而不会违反跨域策略。 var $iframeBody = $("iframe").contents().find("body"); $iframeBody.css("background", blue");
- Clément Gournay
如果由于某种原因您不想要一个 iframe,您可以对您的 PHP 进行 Ajax 调用。 - Ric
@Bharata:错了。如果你将文件内容加载到一个iframe中,你可以像正常的同源iframe一样访问它的内部DOM。 - Maxwell175
11
请注意,如果您使用此方法,请非常小心,因为这将允许您的服务器被用作事实上的代理。因此,应该在身份验证之后或者限制允许访问的网站列表之后再进行操作。 - Maxwell175

9
如果您可以访问嵌入式页面,您可以使用类似 easyXDM 的东西在 iframe 中进行函数调用并返回数据。
如果您无法访问嵌入式页面,则必须使用服务器端解决方案。 使用 PHP,您可以执行一些快速而简单的操作,例如:
    <?php echo file_get_contents('http://url_of_the_iframe/content.php'); ?> 

我无法访问嵌入页面,而且服务器端的解决方案基本上不可行,因为我正在使用CocoaHTTPServer(服务器正在iPhone上运行)。 - D-Nice
在这种情况下是不可能的。请参考http://en.wikipedia.org/wiki/Same_origin_policy获取更详细的信息。 - matthewnessworthy
3
您先生是一位学者和绅士。 - Allen S
非常感谢您的想法,这个答案和这个链接 - https://dev59.com/3Inca4cB1Zd3GeqP_HO6#29501376,帮助我创建了一个解决方法!干杯 - fabriek-huis
@devmatt,使用file_get_contents($_GET['url'])可以获取页面内容,但无法获取DOM内容!这是错误的答案。 - Bharata

7

我们如何使用JS读取iframe中的DOM?这是可能的,不是吗? - Thinh Vu
1
您可以像平常一样读取DOM。例如:document.getElementsByTagName("BODY")[0]; 然后使用window.postMessage将您刚刚在iframe窗口中读取的DOM对象发送到托管iframe窗口的窗口。 - Maksim Luzik

1

有一个解决方法可以实现它。

  1. 首先,将您的 iframe 绑定到具有相对 URL 的目标页面。浏览器将把 iframe 中的站点视为与您的网站相同的域。

  2. 在您的 Web 服务器上,使用重写模块将请求从相对 URL 重定向到绝对 URL。如果您使用 IIS,则建议您检查 IIRF 模块


1
你的意思是服务器向外部位置发送HTTP重定向吗?如果是,至少在Firefox 9中不起作用。我认为其他浏览器也会被识破。 - Anton N
1
他的意思是在服务器上重写请求,这样客户端就不知道它不是正确的URL。 - not my real name

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接