Chrome插件开发(一)

6,412 阅读8分钟

一、认识Chrome扩展开发

作为一个开发人员,我们在日常工作中肯定会用到 Chrome 浏览器,同时也会用到谷歌的一些插件
一、插件是什么?
插件是遵循一定规范的应用程序接口编写出来的程序,而chrome插件则是运行在chrome浏览器上的小程序,能帮我们解决一下工作学习中一些重复繁琐的事情 严格来讲,我们正在说的东西应该叫Chrome扩展(`Chrome Extension`),真正意义上的Chrome插件是更底层的浏览器功能扩展,可能需要对浏览器源码有一定掌握才有能力去开发。鉴于Chrome插件的叫法已经习惯,本文也全部采用这种叫法,但读者需深知本文所描述的Chrome插件实际上指的是Chrome扩展。

Chrome插件是一个用Web技术开发、用来增强浏览器功能的软件,它其实就是一个由HTML、CSS、JS、图片等资源组成的一个.crx后缀的压缩包.

个人猜测crx可能是Chrome Extension如下3个字母的简写:

对于chrome插件来说,最核心的应该是manifest.json这个配置文件了,利用它我们可以定义在什么时机在什么网页执行什么脚本,有一些什么行为,下面先看一下manifest.json的格式:

{
   // 扩展名称
   "name": "MyExtension",
   // 版本。由1到4个整数构成。多个整数间用"."隔开
   "version": "1.0",
   // manifest文件版本号。Chrome18开始必须为2
   "manifest_version": 2,
   // 描述。132个字符以内
   "description": ",
   // 扩展图标。推荐大小16,48,128
   "icons": {
     "16": "image/icon-16.png",
     "48": "image/icon-48.png",
     "128": "image/icon-128.png"
   },
   // 语言
   "default_locale": "en",
   // 地址栏右侧图标管理,含图标及弹出页面的设置等
   // 建议至少保留一个设置,不然扩展图标是暗的
   "browser_action": {
     "default_icon": "image/icon-128.png",
     "default_title": "My Message",
     "default_popup": "html/browser.html"
   },
   // 地址栏最后附加图标。含图标及行为等
   "page_action": {
     "default_icon": "image/icon-48.png",
     "default_title": "My Test",
     "default_popup": "html/page.html"
   },
   // 主题,用于更改整个浏览器的外观
   "theme": {},
   // 指定扩展需要跳转到的URL
   "app": {},
   // 指定扩展进程的background运行环境及运行脚本
   "background": {
     "scripts": [
       "lib/jquery-3.3.1.min.js",
       "js/background.js"
     ],
     "page":"html/background.html"
   },
   // 替换页面
   "chrome_url_overrides": {
     "pageToOverride": "html/overrides.html"
   },
   // 指定在web页面运行的脚本/插入的css及运行/插入时机
   "content_scripts": [{
     "matches": ["https://www.baidu.com/*"],
     "css": ["css/mystyles.css"],
     "js": ["lib/jquery-3.3.1.min.js", "js/content.js"],
     "run_at": "document_idle"
   }],
   // 安全策略
   "content_security_policy": ",
   "file_browser_handlers": [],
   // 扩展的官方主页
   "homepage_url": "http://xxx",
   // 插件在隐私模式下的配置
   "incognito": "spanning",
   // 用户操作意图描述
   "intents": {},
   // 扩展唯一标识。不需要人为指定
   "key": ",
   // 扩展所需chrome的最小版本
   "minimum_chrome_version": "1.0",
   // 消息与本地处理模块映射
   "nacl_modules": [],
   // 是否允许脱机运行
   "offline_enabled": true,
   // ominbox即地址栏。用于响应地址栏的输入事件
   "omnibox": {
     "keyword": "myKey"
   },
   // 选项页。用于在扩展管理页面跳转到选项设置
   "options_page": "aFile.html",
   // 申请权限
   "permissions": [
     "https://www.baidu.com/*",
     "background",
     "tabs"
   ],
   // 扩展。可调用第三方扩展
   "plugins": [{
     "path": "extension_plugin.dll",
     "public": true
   }],
   // 指定所需要的特殊技术。目前只支持"3D"
   "requirements": {},
   // 自动升级
   "update_url": "http://path/to/updateInfo.xml",
   // 指定资源路径,为String数组
   "web_accessible_resources": []
 }

这么多?先写段代码压压惊,真的别被吓着了,虽然可用的属性有这么多,但是常用的就那么几个,我们一个个看一下:

  • name 扩展名称。
  • version 插件的版本。
  • manifest_version manifest配置文件版本。
  • description 对于插件功能的描述。
  • icons 插件的图标 可以为插件找一个好看的图标。
  • browser_action 可以定义插件的图标,点击插件时弹出的页面,以及插件的标题,建议始终保留一个,直接不设置这个属性图标会是灰色的,设置了后才会亮起来。
  • background 背景页,扩展进程的背景运行环境,可以拦截修改请求等等。
  • content_scripts 内容脚本,可以指定在什么时机向什么页面插入什么脚本或者css资源
  • permissions 权限申请项,比如存储权限storage,请求拦截权限webRequest, webRequestBlocking等等。 在了解了这些基础知识之后,剩下的工作就是按照我们想要实现的实际功能,编写代码就好了,下面我们正式开始编写我们的第一个插件,由于是第一个插件,虽然功能很简单,但是我们也要给他取一个响亮的名字“插件终结者”,怎么个终结法,且听我们一一道来。 开发插件可以用常用的前端开发工具、Vscode 或者其他的开发工具,其实也可以用记事本写只是没有提示体验感不好,建议用专业的前端的开发工具,作者这里演示用的是WebStorm

编写好以后呢是这样的

image.png

写好之后怎么让浏览器谷歌浏览器运行起来呢

  • 步骤1:打开谷歌浏览器
  • 步骤2:在浏览器的地址栏输入chrome://extensions/
  • 步骤3:打开右上角的开发者模式的开关,默认是关的,需要手动开启
  • 步骤4:点击左上角的 加载已解压的扩展程序,此时会弹窗一个框让你选择一个文件目录,这时就可以选择我们刚才plugin的哪个文件夹目录放进去之后呢它是这样的

无标题.png 此时上面的logo是灰色的,是因为我们没有在manifest.json中没有加icon的属性,所以没有展示出logo,我们随便在网上找个图片放进去 注意logo尺寸不能太大,建议50*50的图片

无标题2.png 千万注意修改了代码之后我们需要刷新一下插件才能展示最新的

第一个小例子:删除百度搜索主页logo图标

  • 第一步,打开百度找到logo的dom元素

image.png

  • 第二步,在代码中写入css、以下会用到content_scripts这个属性

image.png

image.png

  • 第三步,代码写好以后去浏览器上刷新一下插件,然后打开百度搜索页面,神奇的时刻出现了,logo竟然消失了

image.png

Chrome的核心概念

content-scripts

所谓content-scripts,其实就是Chrome插件中向页面注入脚本的一种形式(虽然名为script,其实还可以包括css的),借助content-scripts我们可以实现通过配置的方式轻松向指定页面注入JS和CSS(如果需要动态注入,可以参考下文),最常见的比如:广告屏蔽、页面CSS定制,等等。

{
  // 需要直接注入页面的JS
  "content_scripts": 
  [
    {
      //"matches": ["http://*/*", "https://*/*"],
      // "<all_urls>" 表示匹配所有地址
      "matches": ["<all_urls>"],
      // 多个JS按顺序注入
      "js": ["js/jquery-1.8.3.js", "js/content-script.js"],
      // JS的注入可以随便一点,但是CSS的注意就要千万小心了,因为一不小心就可能影响全局样式
      "css": ["css/custom.css"],
      // 代码注入的时间,可选值: "document_start", "document_end", or "document_idle",最后一个表示页面空闲时,默认document_idle
      "run_at": "document_start"
    }
  ]
}

特别注意,如果没有主动指定run_atdocument_start(默认为document_idle),下面这种代码是不会生效的:

document.addEventListener('DOMContentLoaded', function() { 
    console.log('我被执行了!'); 
});

content-scripts和原始页面共享DOM,但是不共享JS

background

后台(姑且这么翻译吧),是一个常驻的页面,它的生命周期是插件中所有类型页面中最长的,它随着浏览器的打开而打开,随着浏览器的关闭而关闭,所以通常把需要一直运行的、启动就运行的、全局的代码放在background里面。

background的权限非常高,几乎可以调用所有的Chrome扩展API(除了devtools),而且它可以无限制跨域,也就是可以跨域访问任何网站而无需要求对方设置CORS 配置中,background可以通过page指定一张网页,也可以通过scripts直接指定一个JS,Chrome会自动为这个JS生成一个默认的网页:

{
  // 会一直常驻的后台JS或后台页面
  "background":
  {
    // 2种指定方式,如果指定JS,那么会自动生成一个背景页
    "page": "background.html"
    //"scripts": ["js/background.js"]
  },
}

需要特别说明的是,虽然你可以通过chrome-extension://xxx/background.html直接打开后台页,但是你打开的后台页和真正一直在后台运行的那个页面不是同一个,换句话说,你可以打开无数个background.html,但是真正在后台常驻的只有一个,而且这个你永远看不到它的界面,只能调试它的代码。

popup

popup是点击browser_action或者page_action图标时打开的一个小窗口网页,焦点离开网页就立即关闭,一般用来做一些临时性的交互 popup可以包含任意你想要的HTML内容,并且会自适应大小。可以通过default_popup字段来指定popup页面,也可以调用setPopup()方法。

配置方式:

{
  "browser_action":
  {
    "default_icon": "img/icon.png",
    // 图标悬停时的标题,可选
    "default_title": "这是一个示例Chrome插件",
    "default_popup": "popup.html"
  }
}

image.png

image.png

image.png 需要特别注意的是,由于单击图标打开popup,焦点离开又立即关闭,所以popup页面的生命周期一般很短,需要长时间运行的代码千万不要写在popup里面。

在权限上,它和background非常类似,它们之间最大的不同是生命周期的不同,popup中可以直接通过chrome.extension.getBackgroundPage()获取background的window对象。

本文就介绍到了这里

好了下期再见,请关注

Chrome插件开发(二):讲到浏览器如何通信