原文地址:github.com/HuJiaoHJ/bl…vue
在咱们平时的开发工做中,chrome开发者工具是咱们必不可少的工具,除了Chrome原生的工具以外,还有好比:react
本文主要分享的就是这些开发者工具怎么与页面进行消息通讯的。git
首先,先看一个例子:github
这个开发者工具源码:github.com/HuJiaoHJ/ec…,这个工具是一个支持canvas库 ( easycanvas ) 的chrome调试工具,能对canvas的元素的样式、物理属性等进行修改,达到所见即所得的效果,提升调试效率。感兴趣的小伙伴能够自行了解下~web
本文主要是经过这个工具,分享一下 chrome devtools 通讯相关的知识(chrome devtools的基础开发在这里就不介绍了,不熟悉的小伙伴能够去官网看看~)固然,没有接触过chrome devtools开发的小伙伴,也能够经过这篇文章了解到chrome devtools的基本组成,了解其基本的通讯方式,对平时的工做也能有一些借鉴和帮助哒~chrome
chrome devtools 主要分为三部分:canvas
下面会详细介绍各部分,下面这张图是这三部分之间的通讯全景图:并发
咱们根据这张图,来详细的看看每一个部分的具体实现吧~工具
内容脚本(Content Script)是在网页的上下文中运行的js文件,能够经过此js文件获取DOM和捕获DOM事件。post
网页不能直接与开发者工具(DevTools Page)进行通讯,须要经过在内容脚本中监听网页事件,经过chrome.runtime API将消息传递到后台页面中,从而传递到开发者工具中。
内容脚本能够监听网页的DOM事件或者window.postMessage事件,以下:
window.postMessage({
name: 'hello wolrd'
}, '*');
复制代码
window.addEventListener('message', e => {
if (e.source === window) {
chrome.runtime.sendMessage(e.data);
}
});
复制代码
后台页面,虽然叫页面,实际上是在后台的js脚本。
内容脚本监听的事件触发以后,经过chrome.runtime.sendMessage()方法将消息传递到后台页面(Background Page)中。
后台脚本经过chrome.runtime.onMessage.addListener()方法监听消息,以下:
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (sender.tab) {
const tabId = sender.tab.id;
......
} else {
console.log("sender.tab not defined.");
}
return true;
});
复制代码
后台页面与开发者工具经过长链接进行通讯。(chrome.runtime API)以下:
// 与后台页面消息通讯-长链接
const port = chrome.runtime.connect({name: 'devtools'});
// 监听后台页面消息
port.onMessage.addListener((message) => {
......
});
// 日后台页面发送消息
port.postMessage({
name: 'original',
tabId: chrome.devtools.inspectedWindow.tabId
});
复制代码
chrome.runtime.onConnect.addListener(function (port) {
const extensionListener = function (message, sender, sendResponse) {
if (message.name == 'original') {
......
}
};
port.onMessage.addListener(extensionListener);
port.onDisconnect.addListener(function(port) {
port.onMessage.removeListener(extensionListener);
});
});
复制代码
以上,就介绍了网页与内容脚本、内容脚本与后台页面、后台页面与开发者工具之间的通讯,因此能够发现,网页的消息是经过内容脚本、后台页面,最后到达开发者工具,那么达到内容脚本的消息怎么传递到开发工具的呢?
显而易见,其实就是经过后台页面做为桥,将内容脚本的消息传递到开发者工具中。具体代码以下:
// 做为content script 与 devtool 通讯的桥
const connections = {};
chrome.runtime.onConnect.addListener(function (port) {
const extensionListener = function (message, sender, sendResponse) {
if (message.name == 'original') {
connections[message.tabId] = port;
}
};
port.onMessage.addListener(extensionListener);
port.onDisconnect.addListener(function(port) {
port.onMessage.removeListener(extensionListener);
const tabs = Object.keys(connections);
for (let i = 0, len = tabs.length; i < len; i++) {
if (connections[tabs[i]] == port) {
delete connections[tabs[i]];
break;
}
}
});
});
// 接收内容脚本的消息,并发送到devtool的消息
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (sender.tab) {
const tabId = sender.tab.id;
if (tabId in connections) {
connections[tabId].postMessage(message);
} else {
console.log("Tab not found in connection list.");
}
} else {
console.log("sender.tab not defined.");
}
return true;
});
复制代码
以上,就完成了网页的消息传递到开发者工具的过程,那么开发者工具的消息怎么传递到网页?
开发者工具的消息传递到网页主要有两种方法:
一、直接使用chrome.devtools.inspectedWindow.eval()方法,在网页的上下文中执行js代码,以下:
chrome.devtools.inspectedWindow.eval('console.log(window)');
复制代码
二、开发者工具经过长链接将消息传递到后台页面,在后台页面中,经过调用chrome.tab.excuteScript()方法,在网页中执行js代码,以下:
chrome.tab.excuteScript(tabId, {
code: 'console.log(window)'
});
复制代码
推荐使用第一种方法~
以上,就介绍了网页与开发者工具之间的通讯全过程啦~~~
以上通讯方式在文章一开始提到的工具都用到了,仓库:github.com/HuJiaoHJ/ec…,其实也基本涵盖了 chrome 开发者工具的全部通讯方式~
学习了 chrome devtools 的通讯方式以后,就能愉快的开发本身的开发者工具啦,但愿能对有须要的小伙伴有帮助~~~
喜欢个人文章小伙伴能够去 个人我的博客 点star ⭐️