从 Chrome 扩展中挂钩 Websocket
Posted
技术标签:
【中文标题】从 Chrome 扩展中挂钩 Websocket【英文标题】:Hooking Websockets from a Chrome Extension 【发布时间】:2018-10-04 15:32:55 【问题描述】:我正在尝试创建一个可以挂钩特定页面的 WebSocket 的 Chrome 扩展内容脚本。当前,当页面被访问时,内容脚本会像这样将另一个脚本注入页面:
var s = document.createElement('script');
s.src = chrome.extension.getURL('Script.js');
s.onload = function ()
this.remove();
;
(document.head || document.documentElement).appendChild(s);
然后我的 Script.js 包含 websocket 的 addEventListener。
Window.WebSocket.addEventListener("message",function(event)
console.log("Websocket read");
)
但是当我运行扩展时,我收到一个错误,无法读取未定义的属性 addEventListener。所以我不完全确定这是否是正确的方法。我已经验证脚本确实被注入了页面,但是我将如何在页面的原始 onmessage WebSocket 之上覆盖或创建自己的侦听器。有可能吗?
【问题讨论】:
你能试试像window.WebSocket.addEventListener
这样的小写窗口吗?
您好,当我将其更改为 window.WebSocket.addEventListener
时,我收到此错误:Uncaught TypeError: window.WebSocket.addEventListener is not a function
使用onmessage
代替window.WebSocket.onmessage = function(event) console.debug("WebSocket message received:", event); ;
你在哪里定义了Window.WebSocket
?我不是 chrome 扩展的专家,但我认为这是错误的。在 javascript 中,您应该首先使用 new
关键字创建一个 websocket 实例。
这能回答你的问题吗? ***.com/questions/22868897/…
【参考方案1】:
您可以使用 wshook
覆盖原来的 WebSocket
类并添加可用于任务的回调
您可以直接复制脚本wsHookjs
并粘贴到您的代码之前,或者像普通的javascript一样导入然后开始使用它。
导入库
<script src='wsHook.js'></script>
那么你可以只为之前或之后或两者添加回调来拦截 websocket 发送请求:
wsHook.before = function(data, url, wsObject)
console.log("Sending message to " + url + " : " + data);
// Make sure your program calls `wsClient.onmessage` event handler somewhere.
wsHook.after = function(messageEvent, url, wsObject)
console.log("Received message from " + url + " : " + messageEvent.data);
return messageEvent;
注意:内容脚本可以在页面加载之前加载。有关如何在页面加载之前加载内容脚本的更多信息,您可以查看此post
【讨论】:
这似乎不是我正在寻找的解决方案,因为我不是部署或发布网站或页面的人。相反,我试图将通用脚本注入其他网站或页面,这些网站或页面利用 websockets 并挂钩该特定实例。 @Akali 您可以在页面加载之前注入脚本,有关如何在页面加载之前加载内容脚本的更多信息,请查看here。 你是在暗示我注入了 wsHook.js 的完整性? 即使我的内容脚本在页面加载之前运行,然后我是否会将 @Akali 您不需要在任何网站中注入脚本标签,只需覆盖WebSocket
,这是在您加载内容脚本后由wshook
脚本完成的WebSocket
将由库包装,然后将加载页面,该页面将使用更新后的WebSocket
。【参考方案2】:
WebSocket
是一个类。 addEventListener
函数仅在类的实例中可用。因此,您必须找到网页创建的变量并将侦听器添加到该变量中。例如:
var mySocket = new WebSocket("wss://127.0.0.1:8080");
你会做这样的事情:
mySocket.addEventListener("message", (e) => console.log(e));
但是,这会丢失所有初始消息,这取决于您是否能够访问变量,这在所有情况下可能都不可能。
相反,您可以用自己的类覆盖该类,这样当他们创建 WebSocket
实例时,它实际上就是您的类。
一个例子是这样的:
class MyWebSocket extends WebSocket
__constructor()
super(...arguments);
addEventListener(name, callback)
// call the original event listener
super.addEventListener(name, function()
console.log("Im sneakily listening in here", arguments);
// call their callback
callback(...arguments);
);
// Override the real web socket with your version
window.WebSocket = MyWebSocket;
请记住,上面的代码是伪代码,未经测试。
如果您只想查看套接字数据。您可以打开 chrome 开发工具,单击“ws”过滤器。然后单击列出的 Web 套接字并查看正在传输的原始数据。
这是一个可以在您的上下文脚本中使用的工作示例。
while(document == null || document.head == null);
var s = document.createElement("script");
function hookWebSocket()
window.RealWebSocket = window.WebSocket;
window.WebSocket = function()
var socket = new window.RealWebSocket(...arguments);
socket.addEventListener("message", (e) =>
console.log("The message is: ", e);
);
return socket;
s.innerhtml = `
$hookWebSocket.toString()
hookWebSocket();
`;
document.head.prepend(s);
【讨论】:
是的,我知道如果您找到该变量,则可以这样做,但这不是为依赖它的每个可能站点查找 websocket 变量的通用解决方案。这就是为什么我希望有一种方法可以在内部挂钩它。但我确实认为覆盖 WebSocket 类以便我的实例化而不是原始类可能是唯一的解决方案。 @Akali 我添加了一个工作示例供您使用。 所以这实际上是在文档头部附加或插入脚本标签,然后从那里挂钩 websocket? @Akali 这是一个宾果游戏【参考方案3】:你可以试试这个吗?
s.onload = function ()
this.parentNode.removeChild(this);
;
【讨论】:
脚本的注入部分不能正常工作。以上是关于从 Chrome 扩展中挂钩 Websocket的主要内容,如果未能解决你的问题,请参考以下文章
在 chrome 扩展中,如何从当前 chrome 用户以外的 gmail 用户获取访问令牌?
从 Chrome 扩展程序访问网页的 localStorage