gpt4 book ai didi

javascript - 来自父窗口上下文中 iframe 的 Websocket 连接

转载 作者:行者123 更新时间:2023-12-05 02:17:52 26 4
gpt4 key购买 nike

我有一个页面和页面内的 iframe。两者都托管在同一个域中。我可以完全控制 iframe,但无法控制父页面。

Image

因此,我需要从 iframe 建立一个 websocket 连接,但在父窗口的上下文中,并在我导航出 iframe(到父页面)。

(见图片)就像在 A.html 中建立连接,并在导航到 B 和 C 时保持连接。

这可能吗?

最佳答案

简答:

直接向父窗口注入(inject)脚本可能仍然是一个更优雅的解决方案。

长答案:

Websocket 只是一种与服务器的连接。一旦您创建它 - 它会一直存在于您浏览器的选项卡中,并且如果您卸载创建 websocket 的脚本,它也不会被破坏。

在 iframe 中创建 websockets 的两个问题:

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

您可以尝试在主窗口中创建一个 websocket 工厂。该工厂的实例将负责:

  1. 使用 iframe 提供的数据创建一个 websocket 并将其存储在内部集合属性中
  2. clone 提供了 websocket 事件处理程序,因此即使在卸载原始源时也可以访问它们。如果事件处理程序很简单,它会很好地工作。

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

ma​​in.js(在 main 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);
}

a.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>

关于javascript - 来自父窗口上下文中 iframe 的 Websocket 连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46779908/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com