【问题标题】:JavaScript: sharing data between tabsJavaScript:在选项卡之间共享数据
【发布时间】:2010-11-24 21:17:51
【问题描述】:

在浏览器中打开的标签页之间共享数据的最佳方式是什么?

【问题讨论】:

标签: javascript


【解决方案1】:

如需更现代的解决方案,请查看https://stackoverflow.com/a/12514384/270274

引用:

我坚持使用localStorage 问题中提到的共享本地数据解决方案。就可靠性、效率和浏览器兼容性而言,它似乎是最好的解决方案。

localStorage 已在所有现代浏览器中实现。

storage 事件在 other 选项卡更改 localStorage 时触发。这对于交流来说非常方便。

参考:
http://dev.w3.org/html5/webstorage/
http://dev.w3.org/html5/webstorage/#the-storage-event

【讨论】:

  • 对于存储在localStorage vs sessionStorage中的密钥范围
  • Edge 等浏览器会出现问题,这些浏览器在私有模式下不会在选项卡之间共享本地存储。
  • share data between tabs还有其他几种方式:也可以使用postMessageBroadcastChannel
【解决方案2】:

如果第一个选项卡自动打开第二个选项卡,您可以执行以下操作:

第一个标签:

//open the first tab
var child_window = window.open( ...params... );

第二个标签:

// get reference to first tab
var parent_window = window.opener;

然后,您可以调用函数并在选项卡之间执行各种操作:

// copy var from child window
var var_from_child = child_window.some_var;

// call function in child window
child_window.do_something( 'with', 'these', 'params' )

// copy var from parent window
var var_from_parent = parent_window.some_var;

// call function in child window
parent_window.do_something( 'with', 'these', 'params' )

【讨论】:

  • 我认为这不适用于用户自己在单独的选项卡中打开页面的情况。
  • 但在子窗口仅通过单击父级中的按钮打开并在父级控制时在第二个监视器上全屏显示的情况下......应该会起作用。
【解决方案3】:

另请参阅另一个 StackOverflow 线程:Javascript communication between browser tabs/windows

在我看来有两种很好的方法。根据您的需要,一种可能更适合您。

如果其中任何一个是真的......

  • 不能在服务器端存储信息,
  • 你不能发出很多 http 请求,
  • 您只想存储一点点信息[1],
  • 你想成为纯javascript/客户端,
  • 您只需要它在同一浏览器中的选项卡/窗口之间工作。

-> 然后使用cookies(setCookie 用于发送,getCookie/setTimeout 用于接收)。 一个很好的库是http://theprivateland.com/bncconnector/index.htm

如果其中任何一个是真的......

  • 你要在服务器端存储信息
  • 您想存储大量信息或将其存储在相关事物中(即表格或多维数组[2])
  • 您还需要它跨不同的浏览器(不仅仅是同一浏览器中的选项卡/窗口之间)甚至不同的计算机/用户。

-> 然后使用 Comet(长期持有的 HTTP 请求允许 Web 服务器基本上将数据推送到浏览器)来接收数据。以及发送数据的简短 POST 请求。

Etherpad 和 Facebook Chat 目前使用 Comet 技术。


[1] 当使用 localStorage 时,显然可以存储更多数据,但是由于您会回退到 cookie,因此还不能依赖它。除非您的应用程序仅适用于现代浏览器,在这种情况下这很好。

[2] 复杂的数据也可以存储在 cookie 中(JSON 编码),但这不是很干净(并且对于没有 JSON.stringify/JSON.parse 的浏览器需要后备方法)并且在涉及并发的场景中可能会失败。无法更新 JSON cookie 值的一个属性。您必须解析它,更改一个属性并覆盖该值。这意味着理论上可以撤消另一个编辑。同样,当使用 localStorage 时,这不是问题。

【讨论】:

    【解决方案4】:

    我能想到的唯一方法:与服务器持续进行 ajax 通信以报告其他选项卡上的任何用户操作。

    【讨论】:

      【解决方案5】:

      如何使用 cookie 将数据存储在一个选项卡中并在另一个选项卡中轮询? 我还不知道 cookie 是否在选项卡之间共享,但现在只是一个想法......

      【讨论】:

      • 是的,cookie 仅绑定到域,因此在选项卡之间共享。但是必须不断地轮询cookie,不能监听cookie的变化。
      【解决方案6】:

      我只是看看 Facebook Chat 是如何做到的,他们将向服务器发出的请求保持打开状态不到一分钟。如果数据返回到服务器,则服务器将消息发送回每个打开请求。如果一分钟内没有数据返回,它会重新请求并继续执行此操作(多久,我不确定)。

      【讨论】:

      • 是的,这种方法被称为“彗星”。从客户端来看,这与简单的 AJAX 轮询没有什么不同(例如,发出 AJAX 请求、处理响应并发出另一个请求)。然而,与传统的 AJAX 相比,服务器端是非典型的。服务器完成任务后不会立即返回。相反,它将保持该(例如 PHP 请求)打开并执行类似 while() 的循环,直到有新信息(或超时,即超过 50 秒)。阅读更多:en.wikipedia.org/wiki/Comet_(programming%29。它不是真正的推送技术,但尽可能接近。
      • 为什么不只使用套接字?
      • 这并不能回答这个问题。为什么被接受?问题是如何在浏览器选项卡之间进行通信;不在服务器和浏览器之间。
      • 安德鲁他们可以通过服务器进行通信。 IE。一个选项卡发送消息,其他选项卡接收彗星响应。两个选项卡没有直接的通信方式。根据其他响应共享本地存储和 cookie 也是一个选项。
      • @Dodgyrabbit - 咳嗽 caniuse.com/x-doc-messaging :)
      【解决方案7】:

      鉴于这些选项卡打开时包含相同的站点,您可以考虑构建一个 ajax 脚本,将用户操作报告给服务器,并将其与另一个 ajax 脚本相结合,该脚本读取该报告并在当前窗口中反映它们。

      【讨论】:

      • 您的意思是对服务器进行 ajax 调用以检查是否每隔不到一秒就发生了变化?不是这样的..
      • 如果您需要实时进行,这确实需要一直发出大量请求。然而,这可以通过使服务器保持请求更长的时间直到有数据(或直到超过超时)来解决。另请参阅 [Comet (wikipedia)](en.wikipedia.org/wiki/Comet_(programming%29) 和我的回答。这也是 EtherPad 和 Facebook Chat 的工作方式。
      【解决方案8】:

      如果数据很小,您可以使用 AJAX(正如其他人所建议的那样)或 cookie。请参阅http://www.quirksmode.org/js/cookies.html 了解有关 cookie 的乐趣。

      【讨论】:

        【解决方案9】:

        BroadcastChannel 标准允许这样做。见MDN BroadcastChannel

        // Connection to a broadcast channel
        const bc = new BroadcastChannel('test_channel');
        
        // Example of sending of a very simple message
        bc.postMessage('This is a test message.');
        
        // A handler that only logs the event to the console:
        bc.onmessage = function (ev) { console.log(ev); }
        
        // Disconnect the channel
        bc.close();
        

        【讨论】:

          【解决方案10】:

          一种方法是不要让聊天窗口依赖于选项卡。将选项卡作为单独的 AJAX 组件加载,重新加载时不会影响聊天组件。

          【讨论】:

            【解决方案11】:

            根据要求,您还可以使用 cookie/会话。但是,这意味着数据只能在每个选项卡的第一页加载时访问。

            如果您已经打开了两个选项卡,除非您使用 AJAX,否则更改其中的内容不会更改另一个。

            【讨论】:

            • 不正确,cookie 可以像 AJAX 服务一样被轮询。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-09-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多