【问题标题】:Cross-domain hash change communication跨域哈希变更通信
【发布时间】:2023-03-04 19:01:01
【问题描述】:

请考虑以下两个域:domain1.com 和 domain2。

我从 domain1 打开一个指向 domain2 的 iframe。

现在,我希望这些人能够相互交流,我已经通过在两个域上应用哈希更改事件侦听器成功地实现了这一点。

这样,如果 domain2 使用新哈希调用 parent.location,父窗口 (domain1) 中的哈希将触发。此外,如果我从父级将其 src 属性更改为新的哈希,则会在 iframe 中触发哈希更改事件。

这很好用!

麻烦来了:

浏览器中的后退和前进功能变得混乱。简单地说,通过创建两个哈希实例,浏览器的后退按钮必须点击两次才能更改父哈希,因为它必须先循环遍历 iframe 的哈希。

如何在不破坏历史对象的情况下与跨域 iframe 进行双向通信?

谢谢!

【问题讨论】:

  • 我想到的一种可能(丑陋!)的解决方案:我可以在 domain1 上附加一个指向 domain2 的脚本,如下所示:

标签: javascript html iframe cross-domain hashchange


【解决方案1】:

使用easyXDM,它是一个为您完成所有繁重工作的javascript库,使您能够在包括IE6在内的所有浏览器中进行跨域通信和RPC。

这不会对任何当前浏览器(甚至 IE6)使用 HashTransport,因此不会更改历史记录。

你不会找到更好的..

您可以在 Script Junkie article 中了解它的一些内部工作原理,或直接访问 readme at github

【讨论】:

  • 嗨,肖恩。哇,真是令人印象深刻的作品。我现在正在实施!会让你知道它对我来说是如何工作的。到目前为止,谢谢,伙计
  • 顺便问一下,哪些浏览器会使用HashTransport?需要阻止它们,因为它会破坏我现有的用于书签和导航的哈希实现。
  • 谢谢,不胜感激。自述文件中列出了所有支持的“A 级”浏览器,这些不会使用 HashTransport。
  • 啊,好吧。我现在已经实现了。再次感谢!像魅力一样工作。
  • 酷 :) 您在理解如何使用它时遇到任何问题吗?自述文件是否足够?
【解决方案2】:

另一种跨域通信技术是(ab)使用window.name。它需要一个 iframe 最初具有一个相同域的 src,然后您移动到另一个设置 window.name 的域,然后退回到原始源(退回历史)。这个想法是 window.name 除非明确设置,否则不会更改,这意味着您可以跨域传输 window.name 数据。

此技术在以下位置有更详细的描述:
- http://skysanders.net/subtext/archive/2010/10/11/leveraging-window.name-transport-for-secure-and-efficient-cross-domain-communications.aspx
- http://jectbd.com/?p=611

一定要选择避免在 IE 中点击声音的实现。

不幸的是,它仍然会影响您的历史记录,但它向前迈了一步,然后又回到了它所在的历史记录点。不过,一个很大的好处是您不必解析和编码 URI 字符串,而是可以立即使用 JSON。

Using JSON lib for example

// access window.name from parent frame
// note: only when iframe stepped back to same domain.
var data = JSON.parse( iframe.contentWindow.name );

// set child frame name
// note: only when iframe stepped back to same domain.
iframe.contentWindow.name = JSON.stringify( {
    foo : "bar"
} ); // to JSON string

// set own name ( child frame )
window.name = JSON.stringify( {
    foo : "bar"
} ); // to JSON string

cookie 技术也是可行的,对于这两种技术,如果您想避免历史更改但仍需要 http 请求,则需要在目标 iframe 中执行 ajax 请求。 所以:

  1. 向 iframe x 发送数据(使用 cookie 或 window.name 技术)
  2. 在 iframe x 中使用轮询器捕获数据
  3. 在 iframe x 中执行 ajax 请求。
  4. 将数据发送回 iframe y(使用 cookie 或 window.name 技术)
  5. 在 iframe y 中使用轮询器捕获数据
  6. 做个骗子。

任何页面刷新 (httprequest) 或 url 更改都会更新历史记录(旧版本或所有 IE 版本除外),因此需要更多代码。

【讨论】:

  • 感谢您的精心解答!非常感激。但是,您确定这适用于跨域吗?当我尝试从 iframe 访问 window.name 时,我得到: Error: Permission denied for domain1.com> to get property Window.name from domain2.com>.
  • 查看一下,您使用的是哪个浏览器?
  • macOS 上的 Firefox 3.6.12。也发生在 Chrome 7 中:不安全的 JavaScript 尝试从 URL domain2.com 的框架访问具有 URL domain1.com 的框架。域、协议和端口必须匹配。
  • 我的道歉,还有更多的技术。查看文章链接并更新了我的 awnser。在任何情况下,任何技术都会让人感觉像是 hack =(
  • 不用担心。根据 Script Junkie 文章 Sean 发布的 window.name 将无法在较新的浏览器版本中工作。我将使用 easyXDM 框架。非常感谢您的时间和帮助!
猜你喜欢
  • 2015-09-13
  • 2011-10-30
  • 2011-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-14
  • 1970-01-01
  • 2013-02-10
相关资源
最近更新 更多