2017-10-16 437 views
1

我有一个页面和页面内的iframe。两者都托管在同一个域中。我完全控制了iframe,但没有父页面的控制权。从父窗口的上下文中的iframe的WebSocket连接

Image

所以我需要建立从IFRAME一个WebSocket连接,但在父窗口,并保持它活着,而我从导航的iframe的背景下(到其他菜单项父页面)。

(见图片)像建立在A.html连接,并保持它活着,而导航到B和C.

这可能吗?

回答

0

简短的回答:

直接脚本注入到父窗口仍可能是一个更好的解决方案。

龙答:

的WebSocket只是一种连接到服务器。一旦你创建了它 - 它会一直存在于浏览器的标签中,如果你卸载了创建websocket的脚本,它就不会被销毁。

两个问题与iframe中,创造的WebSockets:

  1. 你可能不希望在每次加载相同的iframe中的内容时创建一个新的WebSocket连接。
  2. 一旦您的iframe被卸载 - 所有websocket的事件处理程序都会丢失(如onopen,onclose,onmessage等)。

您可以尝试在主窗口上创建websocket工厂。这家工厂的实例将负责:

  1. 使用从一个iframe提供的数据创建的WebSocket,并将其存储在内部集合属性
  2. 克隆提供的WebSocket事件处理程序,使他们可达甚至当他们的原始来源被卸载。如果事件处理程序很简单,它将正常工作。

函数克隆存在一些已知问题 - 即,如果它们使用iframe脚本中定义的外部闭包 - 那么闭包将会丢失。您可能想要对克隆库进行研究。

main.js(加载在主的index.html):

var socketsCollection = new SocketsCollection(); 

function SocketsCollection() { 
    this.collection = {}; 

    this.add = function(key, obj) { 
     if (this.exists(key)) return; 

     // clone websocket event handlers 
     // PS: this is not the best solution to clone a function. Need a better research here 
     eval("var onopen = " + obj.onopen.toString()); 
     eval("var onclose = " + obj.onclose.toString()); 
     eval("var onmessage = " + obj.onmessage.toString()); 

     // create websocket 
     var ws = new WebSocket(obj.url); 
     ws.onopen = function(e) { 
      onopen(e, key, ws); 
     }; 
     ws.onclose = function(e) { 
      onclose(e, key, ws); 
     } 
     ws.onmessage = function(e) { 
      onmessage(e, key, ws); 
     } 

     this.collection[key] = { 
      key: key, 
      ws: ws 
     }; 

     // test websocket is alive 
     var self = this; 
     var counter = 1; 
     window.setInterval(function() { 
      console.log('testing ' + key); 
      self.collection[key].ws.send('ping # ' + counter + ' websocket ' + key); 
      counter++; 
     }, 2000); 
    } 

    this.exists = function(key){ 
     return this.collection[key] !== undefined; 
    } 
} 

iframed.js:

function foo(window, socketKey) { 
    if (window.socketsCollection.exists(socketKey)) return; 

    var newSocketData = { 
     url: "wss://echo.websocket.org/", 
     onopen: function(e, key, ws) { 
      console.log(key + ' is OPEN', ws.readyState) 
      ws.send('Hello socket ' + key); 
     }, 
     onclose: function(e, key, ws) { 
      console.log(key + ' is CLOSED', ws.readyState) 
     }, 
     onmessage: function (e, key, ws) { 
      console.log(key + ' response: ', e.data); 
     } 
    }; 

    window.socketsCollection.add(socketKey, newSocketData); 
} 

一个。HTML:

<script src="iframed.js"></script> 
<script> 
    foo.call(window.parent, window.parent, 'A'); 
</script> 

b.html:

<script src="iframed.js"></script> 
<script> 
    foo.call(window.parent, window.parent, 'B'); 
</script> 
相关问题