一、简介

1、简介

扩展程序(Extensions)是可定制浏览体验的小型软件程序,用户可以根据个人需要或偏好来定制Chrome的功能和行为。它由Web开发技术(HTML、CSS和JavaScript)开发的相互关联的不同组件组成,组件主要包括:后台脚本、内容脚本、选项页、UI界面和各种逻辑文件,这些组件共同实现一系列功能。

2、扩展程序文件

扩展程序文件被压缩到一个.crx软件包中,用户可以下载并安装。这意味着扩展程序与普通的Web应用程序不同,它不依赖于Web上的内容。

扩展程序中的文件可以通过使用相对URL来引用,就像普通HTML页面中的文件一样:<img src="images/my_image.png">;也可以使用绝对URL来访问每个文件:chrome-extension://<extensionID>/<pathToFile>,其中,extensionID是扩展系统为每个扩展程序生成的唯一标识符,在解压扩展程序时ID可能会发生变化。因此建议如果依赖了绝对URL可以使用chrome.runtime.getURL()方法来避免在开发过程中对ID的硬编码。

扩展程序必须在浏览器工具栏中有一个图标,使用工具栏图标可以轻松访问扩展程序并让用户知道安装了哪些扩展。大多数用户将通过单击图标弹出的窗口进行交互。

3、扩展程序结构

扩展程序的结构取决于其功能,许多健壮的扩展程序包括多个组件:

  • Manifest

扩展程序需要定义一个Manifest文件(manifest.json),该文件为浏览器提供了有关扩展的信息,例如:最重要的文件和扩展可能使用的功能。

  • Background Script

后台脚本是扩展程序的事件处理程序,包含对浏览器事件的监听器。它处于休眠状态直到一个事件被触发执行指定的业务逻辑;一个有效的后台脚本仅在需要时才被加载。

  • UI Elements

扩展程序的用户界面应有目的且最少,用户界面应该自定义或增强浏览体验,而不会分散注意力。

扩展的UI页面(例如弹出窗口)中可以包含具有JavaScript逻辑的普通HTML页面,也可以调用tabs.createwindow.open()来显示扩展程序中存在的其他HTML页面。

使用页面操作和弹出窗口的扩展程序可以使用声明性内容API在后台脚本中为用户使用弹出窗口设置规则;满足条件后,后台脚本会与弹出窗口进行通信,以使用户可以点击其图标。

  • Content scripts

扩展程序利用内容脚本读取或写入Web页面,内容脚本中包含JavaScript,JS脚本在已加载到浏览器页面的上下文中执行。

内容脚本可以通过Storage API存储值来交换消息实现与其父扩展页面的通信。

  • Options Page

就像扩展程序允许用户自定义Chrome浏览器一样,选项页面也可以自定义扩展程序。选项可用于启用扩展程序的功能特性,并允许用户选择需要的功能。

4、Chrome API

扩展程序除了可以访问与网页相同的API外,还可以使用特定于扩展程序的API,例如:扩展程序和网页都可以访问标准的window.open()方法来打开URL,但扩展程序可以通过使用Chrome API tabs.create()方法来指定在哪个窗口中显示URL。

大多数Chrome API方法都是异步的,如果扩展程序需要知道异步操作的结果,则可以将回调函数传递给API方法。

如果扩展程序需要将用户当前选择的标签导航到新的URL,则需要获取当前标签的ID,然后将该标签的地址更新为新的URL即可。

样例:查询选项卡并更新其URL。

  • 错误的写法
var tab = chrome.tabs.query({'active': true});
chrome.tabs.update(tab.id, {url:newUrl});
someOtherFunction();
  • 正确的写法
chrome.tabs.query({'active': true}, function(tabs) {
	chrome.tabs.update(tabs[0].id, {url: newUrl});
});
someOtherFunction();

5、页面间通信

扩展程序中的不同组件通常需要相互通信,不同的HTML页面可以通过chrome.extension的方法,例如:getViews()、getBackgroundPage()等找到彼此。如果一个页面引用了其他的扩展程序页面,在第一个页面中可以调用其他页面上的函数并操作其DOM。而且扩展程序的所有组件都可以访问并使用Storage API存储值,通过消息传递进行通信。

6、保存数据和隐身模式

扩展程序可以使用存储API、HTML5 Web存储API或通过发出保存数据的服务器请求来保存数据。当扩展程序要保存某些内容时,需要先考虑它是否来自隐身窗口。默认情况下,扩展程序不会在隐身窗口中运行。

隐身模式保证该窗口不会留下任何痕迹。在使用隐身窗口处理数据时,扩展程序应遵守这一承诺。如果扩展程序通常保存浏览历史记录,请不要保存隐身窗口中的历史记录。

可以通过检查tab.Tabwindows.Window对象的隐身属性来判断窗口是否处于隐身模式:

function saveTabData(tab) {
	if (tab.incognito) {
		return;
	} else {
		chrome.storage.local.set({data: tab.url});
	}
}

二、Hello Extensions

此扩展程序的功能为点击扩展程序图标,打开一个HTML页面,显示:Hello Extensions。
首先创建扩展程序文件目录:hello-extensions

1、创建Manifest文件

创建manifest.json文件,在browser_action中声明了一个弹出文件和图标,在commands中定义了启用功能的快捷键:

{
	"name": "Hello Extensions",
    "description" : "Base Level Extension",
    "version": "1.0",
    "manifest_version": 2,
    "browser_action": {
		"default_popup": "hello.html",
		"default_icon": "hello_extensions.png"
    },
	"commands": {
		"_execute_browser_action": {
			"suggested_key": {
				"default": "Ctrl+Shift+0",
				"mac": "MacCtrl+Shift+0"
			},
			"description": "Opens hello.html"
		}
    }
}

2、创建扩展程序文件

  • 图标文件

hello-extensions/hello_extensions.png

  • HTML文件

hello.html

<html>
	<body>
		<h1>Hello Extensions</h1>
	</body>
</html>

3、安装扩展程序

  • 打开Chrome扩展

在浏览器导航栏中输入:chrome://extensions

  • 加载已解压的扩展程序

  • 效果

三、样例

此扩展程序的功能为点击扩展程序将弹出窗口,点击窗口中的按钮可以更改背景颜色。
首先创建扩展程序文件目录:change-bgcolor

1、创建Manifest文件

创建manifest.json文件:

{
	"name": "Change BackgourndColor",
	"version": "1.0",
	"description": "Build an Extension!",
	"permissions": ["activeTab", "declarativeContent", "storage"],
	"background": {
		"scripts": ["background.js"],
		"persistent": false
	},
	"page_action": {
		"default_popup": "popup.html",
		"default_icon": {
			"16": "images/icon16.png",
			"32": "images/icon32.png",
			"48": "images/icon48.png"
		}
    },
	"icons": {
		"16": "images/color.png"
	},
	"manifest_version": 2
}

在此文件中,配置了后台脚本文件background.js;并且声明要使用Storage API、declarativeContent API和activeTab API,大多数API都必须在Mainfest文件的permissions中注册后,扩展程序才能使用;在page_action中指定以弹出窗口方式打开popup.html,并定义图标文件。

2、创建后台脚本文件

创建background.js

chrome.runtime.onInstalled.addListener(function() {
	chrome.storage.sync.set({color: '#3aa757'}, function() {
		console.log("The color is green.");
	});
	chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
		chrome.declarativeContent.onPageChanged.addRules([{
			conditions: [new chrome.declarativeContent.PageStateMatcher({
				pageUrl: {hostEquals: 'www.baidu.com'},
			})],
			actions: [new chrome.declarativeContent.ShowPageAction()]
		}]);
	});
});

此脚本中包含一个runtime.onInstalled的监听事件,在监听器内部使用存储API存储数据,并使用declarativeContent API添加声明的规则:此扩展程序只有在页面的URL为’www.baidu.com’时生效。

3、创建扩展程序文件

  • 图标文件

扩展程序图标:

images/icon16.png
images/icon32.png
images/icon48.png

扩展程序管理页面上的图标:

images/color.png
  • HTML文件

popup.html

<!DOCTYPE html>
<html>
<head>
  <style>
	button {
	  height: 30px;
	  width: 30px;
	  outline: none;
	}
  </style>
</head>
<body>
  <button id="changeColor"></button>
  <script src="popup.js"></script>
</body>
</html>
  • 内容脚本

popup.js

let changeColor = document.getElementById('changeColor');

chrome.storage.sync.get('color', function(data) {
	changeColor.style.backgroundColor = data.color;
	changeColor.setAttribute('value', data.color);
});

changeColor.onclick = function(element) {
	let color = element.target.value;
	chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
		chrome.tabs.executeScript(tabs[0].id, {code: 'document.body.style.backgroundColor = "' + color + '";'});
	});
};
  • 效果

访问www.baidu.com

4、为用户提供选项

该扩展程序当前仅允许用户将背景更改为绿色,添加一个选项页面可以使用户更好地控制扩展功能,进一步自定义其浏览体验。

  • 创建选项页面

options.html

<!DOCTYPE html>
<html>
	<head>
		<style>
			button {
				height: 30px;
				width: 30px;
				outline: none;
				margin: 10px;
			}
		</style>
	</head>
	<body>
		<div id="buttonDiv"></div>
		<div>
			<p>Choose a different background color!</p>
		</div>
	</body>
	<script src="options.js"></script>
</html>
  • 添加选项逻辑

创建options.js

let page = document.getElementById('buttonDiv');
const buttonColors = ['#3aa757', '#e8453c', '#f9bb2d', '#4688f1'];

function constructOptions(buttonColors) {
	for (let item of buttonColors) {
		let button = document.createElement('button');
		button.style.backgroundColor = item;
		button.addEventListener('click', function() {
			chrome.storage.sync.set({color: item}, function() {
				console.log('color is ' + item);
			});
		});
		page.appendChild(button);
	}
}
constructOptions(buttonColors);
  • 在Manifest文件中注册
{
	"name": "Change BackgourndColor",
	...
	"options_page": "options.html",
	...
	"manifest_version": 2
}

在扩展程序管理页面中,点击扩展程序的”详细信息”按钮,在打开的页面中再点击”扩展程序选项”按钮:

选择一种颜色后,点击扩展程序弹出的窗口中按钮的颜色即为选择的颜色:

四、调试

1、日志查看

使用chrome://extensions打开Chrome扩展程序,找到对应的扩展程序,点击”错误”按钮即可查看错误日志。

2、调试

  • Background Page调试

在扩展程序管理页面中,点击扩展程序卡片中的”背景页”链接,将会打开DevTools面板;点击重新加载按钮可以重新加载后台脚本,即可打断点调试。

附: