正文
我们经常为了额外的功能,会在浏览器中安装插件。在一次需求的开发中,发现原来插件开发距离我们并不遥远, 就是用Javascript实现的。
下面简单讲一个示例。
manifest.json 配置文件内容:
{
    "manifest_version": 3,
    "name":"ajaxCrawler",
    "version":"1.0",
    "description":"ajax message crawler",
    "icons":{
        "48":"images/48.png"
    },
    "permissions": [
        "webRequest"
    ],
    "host_permissions": [
        "<all_urls>"
    ],
    "background": {
        "service_worker": "js/background.js"
    },
    "content_scripts": [
        {
            "matches":["<all_urls>"],
            "js":["js/content.js"],
            "run_at": "document_start"
        }
    ],
    "web_accessible_resources": [{
        "matches": ["<all_urls>"],
        "resources": ["js/ajax.js"]
    }]
}
content_scripts 中的js文件是插件的主体部分,负责 项目页面 与 background 之间的交互。

web_accessible_resources 中的js文件可以被允许写入到 项目页面 中去。background 具有与服务API交互的能力。
ajax异步请求监听
下面结合上面说一下ajax异步请求监听的原理。
在content.js中把ajax.js写入到 项目页面 中:
function injectedScript (path) {
  const scriptNode = document.createElement('script');
  scriptNode.src= chrome.runtime.getURL(path);
  document.documentElement.appendChild(scriptNode);
  return scriptNode;
}
injectedScript('js/ajax.js').addEventListener('load', () => {
  console.log("load");
});
ajax.js 中把监听到的信息发送到 content.js:
postMessage({
    type: 'crawler-data',
    data: 'detail',
});
content.js 收到后再转发到 background.js 中:
window.addEventListener("message", function (event) {
  const event_data = event.data;
  if (event_data.type === 'crawler-data') {
      console.log('addEventListener');
      chrome.runtime.sendMessage({type: 'send-crawler-data', detail: event_data.data});
  }
}, false);
background.js 中监听 content.js 发送来的信息,进行进一步处理,如发送到指定地址:
const receive_url = 'https://www.baidu.com/search';
chrome.runtime.onMessage.addListener(async (request, sender, sendResponse) => {
    if (request.type === 'send-crawler-data') {
        const reponse = fetch(receive_url, {
            method: 'post',
            header: {
                'Content-Type':'application/x-www-form-urlencoded: charset=utf-8'
            },
            body: 'detail=' + JSON.stringify(request.detail)
        }).then(function(res) {
            console.log('succ');
            console.log(res);
        }).catch(function(err){
            console.log('error');
            console.log(err);
        });
    }
    return true;
})
更多
更多入门的内容,可以看下:
插件按钮与页面交互的教学视频:https://www.bilibili.com/video/BV1wP4y1m7YK
爬取项目页面内容的教学文档:https://segmentfault.com/a/1190000040837837
谷歌浏览器插件开发后台网络请求、缓存、tabs使用教程:https://www.bilibili.com/video/BV1114y1S7WG
还有一个可以阅读 插件源码 的插件 Chrome extension source viewer:https://github.com/Rob--W/crxviewer
参考资料
Chrome 插件特性及实战场景案例分析 https://zhuanlan.zhihu.com/p/436564672
chrome扩展-通信方式 https://zhuanlan.zhihu.com/p/610018797