chrome 浏览器插件(扩展)开发入门指南

chrome 插件,也叫扩展,几乎对所有 chromium 内核的浏览器都适用,现在常见的360浏览器、QQ浏览器、搜狗浏览器,都是兼容的。

最终形式是打包成以crx为扩展名的包,可以发布到chrome扩展市场,也可以通过手动拖进扩展中心进行安装。


插件的意义

通过插件我们可以在网页解析显示出来后再注入脚本,方便地提取网页内容,实时采集和监听。插件还可以拥有面板页和背景脚本,背景脚本具有强大的操作权限,可以控制 Tab,在多个 Tab 之间传递数据;而面板页可以看作是主控台,提供界面来操作插件。

如果你的客户希望在他人的网站上看到更多扩展内容,或者你在采集工作上遇到严格的跨域限制,插件可能是个不错的解决方案。


基本配置

先来看看目录结构

project
- css
- js
- manifest.json
- icon.png
- popup.html

项目下必须有manifest.json文件,相当于入口配置文件,请留意下面源码的注释

{
  "manifest_version": 2, // 这里必须是2,不能改
  "name": "快速填充", // 插件名
  "description": "", // 插件描述
  "version": "0.1.0", // 版本
  "permissions": [ // 定义要用到的权限,会在用户安装插件时弹出提示用到哪些权限
    "tabs",// 允许控制所有tab
    "activeTab",// 允许控制当前tab
    "background",// 允许有背景脚本
    "<all_urls>"// 允许与所有url交换数据,也可写某个网址,如"http://*.flickr.com/"
  ],
  browser_action": { // 插件安装后右上角会出现这个插件的按钮
    "default_icon": "icon.png", // 按钮的图标
    "default_title": "查看填充记录", // 鼠标停留在按钮上会显示的标题
    "default_popup": "popup.html" // 鼠标点击按钮后会快速显示的一个网页浮层
  },
  "background": { // 插件背景脚本
    "scripts": ["js/libs/jquery.js", "js/background.js"], // 背景脚本,依送执行
    "persistent": true // 是否持续存在,作为背景页,那是必须的
  },
  "content_scripts": [
    { // 插件单元脚本
      "matches": [ // 只要网址匹配该数组中任意一个,都会在网页上注入单元脚本
        "http://www.gxxsite.com/*",
        "http://blog.gxxsite.com/*",
        "http://me.gxxsite.com/*"
      ],
      "all_frames": true, // 是否对网址匹配的iframe也注入脚本
      "css": ["css/css.css"], // 注入脚本的同时加载样式,依次加载数组中多个css文件
      "js": ["js/libs/jquery.js", "js/page.js"] // 要注入的脚本,依次加载数组中多个js文件
    }
  ]
}

如何开始

  1. 打开扩展程序(仅以 Chrome 浏览器为例,其他浏览有的叫“应用中心”,“我的应用”)

    chrome://extensions/

  2. 点击“加载已解压的扩展程序”,选择你的插件目录,就可以了

  3. 每次修改,都需要点一次“重新加载”来刷新插件,然后再网页上刷新一次来看效果

    QQ20180131-175601@2x


单页实例

先来一发Hello world,开启插件之旅(源码在 github示例项目firstdemo分支)

manifest.json

{
  "manifest_version": 2,
  "name": "chrome扩展示例",
  "description": "chrome扩展示例",
  "version": "1.0.0",
  "permissions": [
    "activeTab"
  ],
  "browser_action": {
    "default_icon": "icon.png",
    "default_title": "chrome扩展示例"
  },
  "content_scripts": [
    {
      "matches": [
        "https://*.gxxsite.com/*"
      ],
      "all_frames": false,
      "css": ["css/css.css"],
      "js": ["js/libs/jquery.js", "js/page.js"]
    }
  ]
}

css.css

.hello{
  position: fixed;
  left: 0;
  bottom: 30px;
  width: 140px;
  height: 24px;
  line-height: 24px;
  font-size: 14px;
  text-align: center;
  color: #ffffff;
  background: #444444;
}

page.js

$('body').append('<div class="hello">hello world</div>')

交互实例

交互实例加入了常用到的多种操作方式(源码在 github示例项目master分支)

由于代码较多,就不贴出了,下面我分别解释下几种交互方式及代码片段

  1. page: 发出消息到背景进程,并提供一个响应背景进程返回结果的方法

     chrome.runtime.sendMessage({
       color: $(this).data('color')
     }, function (response) {
       // console.log(response)
       alert('另一个网页已成功修改了背景色为 ' + response.colorCode)
     })
    
  2. background: 接受请求,分析请求,有必要的时候向指定的tab发出消息

     chrome.runtime.onMessage.addListener(
       function(request, sender, sendResponse) {
         // 收到message
         // 判断是不是简历
         let urlPattern = []
         if (!/me\./.test(sender.url)) {
           urlPattern.push('https://me.gxxsite.com/*')
         }
         if (!/www\./.test(sender.url)) {
           urlPattern.push('https://www.gxxsite.com/*')
         }
         // console.log(urlPattern)
         chrome.tabs.query({url: urlPattern}, (tabs) => {
           if (tabs) {
             for (let i = 0; i < tabs.length; i++) {
               chrome.tabs.sendMessage(tabs[i].id, {color: request.color}, function(response) {
                 sendResponse({
                   ok: 1,
                   colorCode: response.colorCode
                 })
               })
             }
           } else {
             sendResponse({
               ok: 0
             })
           }
         })
         return true
       }
     )
    

    == sendResponse 可以是异步的,但在异步之前要先return true让发送消息的页面知道情况,否则会报错 ==

  3. page: 接收来自background的请求,进行相应操作并返回结果

     chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
       let colorCode = request.color === 'red' ? '#ff0000' : request.color === 'green' ? '#00ff00' : '#0000ff'
       $('body').css('backgroundColor', colorCode)
       sendResponse({
         colorCode: colorCode
       })
     })
    

写在后面

其实两个例子都写得很简单,但我觉得核心交互是灵魂,结合 ajax 之后是很可怕的,可以尽情发挥你的想象力


参考API

https://developer.chrome.com/extensions
http://open.chrome.360.cn/extension_dev/extension.html

若您觉得我的博文对您有帮助,欢迎点击下方按钮对我打赏
打赏