严格来讲,我们正在说的东西应该叫Chrome扩展(Chrome Extension),真正意义上的Chrome插件是更底层的浏览器功能扩展,可能需要对浏览器源码有一定掌握才有能力去开发。鉴于Chrome插件的叫法已经习惯,本文也全部采用这种叫法,但读者需深知本文所描述的Chrome插件实际上指的是Chrome扩展。
Chrome插件是一个用Web技术开发、用来增强浏览器功能的软件,它其实就是一个由HTML、CSS、JS、图片等资源组成的一个.crx后缀的压缩包.
增强浏览器功能,轻松实现属于自己的“定制版”浏览器,等等。
Chrome插件提供了很多实用API供我们使用,包括但不限于:
书签控制;
下载控制;
窗口控制;
标签控制;
网络请求控制,各类事件监听;
自定义原生菜单;
完善的通信机制;
等等;
从右上角菜单->更多工具->扩展程序可以进入 插件管理页面,也可以直接在地址栏输入 chrome://extensions 访问。
勾选开发者模式即可以文件夹的形式直接加载插件,否则只能安装.crx格式的文件。Chrome要求插件必须从它的Chrome应用商店安装,其它任何网站下载的都无法直接安装,所以,其实我们可以把crx文件解压,然后通过开发者模式直接加载。
开发中,代码有任何改动都必须重新加载插件,只需要在插件管理页按下Ctrl+R即可,以防万一最好还把页面刷新一下。
manifest.json
这是一个Chrome插件最重要也是必不可少的文件,用来配置所有和插件相关的配置,必须放在根目录。其中,manifest_version、name、version3个是必不可少的,description和icons是推荐的。
{
// 清单文件的版本,这个必须写,而且必须是2
"manifest_version": 2,
// 插件的名称
"name": "demo",
// 插件的版本
"version": "1.0.0",
// 插件描述
"description": "简单的Chrome扩展demo",
// 图标,一般偷懒全部用一个尺寸的也没问题
"icons":
{
"16": "img/icon.png",
"48": "img/icon.png",
"128": "img/icon.png"
},
// 会一直常驻的后台JS或后台页面
"background":
{
// 2种指定方式,如果指定JS,那么会自动生成一个背景页
"page": "background.html"
//"scripts": ["js/background.js"]
},
// 浏览器右上角图标设置,browser_action、page_action、app必须三选一
"browser_action":
{
"default_icon": "img/icon.png",
// 图标悬停时的标题,可选
"default_title": "这是一个示例Chrome插件",
"default_popup": "popup.html"
},
// 当某些特定页面打开才显示的图标
/*"page_action":
{
"default_icon": "img/icon.png",
"default_title": "我是pageAction",
"default_popup": "popup.html"
},*/
// 需要直接注入页面的JS
"content_scripts":
[
{
//"matches": ["http://*/*", "https://*/*"],
// "" 表示匹配所有地址
"matches": ["" ],
// 多个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"
},
// 这里仅仅是为了演示content-script可以配置多个规则
{
"matches": ["*://*/*.png", "*://*/*.jpg", "*://*/*.gif", "*://*/*.bmp"],
"js": ["js/show-image-content-size.js"]
}
],
// 权限申请
"permissions":
[
"contextMenus", // 右键菜单
"tabs", // 标签
"notifications", // 通知
"webRequest", // web请求
"webRequestBlocking",
"storage", // 插件本地存储
"http://*/*", // 可以通过executeScript或者insertCSS访问的网站
"https://*/*" // 可以通过executeScript或者insertCSS访问的网站
],
// 普通页面能够直接访问的插件资源列表,如果不设置是无法直接访问的
"web_accessible_resources": ["js/inject.js"],
// 插件主页,这个很重要,不要浪费了这个免费广告位
"homepage_url": "https://www.baidu.com",
// 覆盖浏览器默认页面
"chrome_url_overrides":
{
// 覆盖浏览器默认的新标签页
"newtab": "newtab.html"
},
// Chrome40以前的插件配置页写法
"options_page": "options.html",
// Chrome40以后的插件配置页写法,如果2个都写,新版Chrome只认后面这一个
"options_ui":
{
"page": "options.html",
// 添加一些默认的样式,推荐使用
"chrome_style": true
},
// 向地址栏注册一个关键字以提供搜索建议,只能设置一个关键字
"omnibox": { "keyword" : "go" },
// 默认语言
"default_locale": "zh_CN",
// devtools页面入口,注意只能指向一个HTML文件,不能是JS文件
"devtools_page": "devtools.html"
}
因为我只需要修改User-Agent和Accept-Language,所以不需要其他的页面选项之类的,只需要一个background和申请对应权限即可,我的大概是这个样子
{
"name": "__MSG_chrome_extension_name__",
"description": "__MSG_chrome_extension_description__",
"version": "0.2",
"default_locale": "en_US",
"browser_action": {
"default_title": "__MSG_browser_action_title__",
"default_icon": "24.png"
},
"background": {
"scripts": [ "background.js" ]
},
"icons": {
"128": "128.png",
"16": "16.png",
"48": "48.png"
},
"manifest_version": 2,
"permissions": [ "webRequest", "webRequestBlocking", "\u003Call_urls>" ]
}
对于相应的开发方法和api呢,我们可以去chrome官方查看,或者找国内浏览器的汉化版说明
360极速浏览器开放平台.
经过查询,我们需要的是chrome.webRequest api,所以我们要在manifest.json中申请对应的权限,
修改的是http头参数,并且是在发送header之前我们需要的是chrome.webRequest.onBeforeSendHeaders api
接口简介.
按照该api进行开发,根据文档的说明,传入需要的requestHeaders参数,即可修改User-Agent参数
而对于Accept-Language参数,使用默认参数对header进行打印的时候是看不到这个参数的,所以对于api需要传入另一个参数extraHeaders才可以修改。
function replaceHeader(user_agent, requestHeaders) {
console.log("1111");
var newHeaders = [];
for (var i = 0; i < requestHeaders.length; i++)
{ console.log(requestHeaders[i].name);
if (requestHeaders[i].name == "User-Agent")
newHeaders.push({name: "User-Agent", value: "Mozilla/5.0 (MSIE 10.0; Windows NT 6.1; Trident/5.0)"});
else
{
newHeaders.push(requestHeaders[i]);
}
}
newHeaders.push({name: "User-Agent11", value: "45465"});
newHeaders.push({name: "Accept-Language", value: "en-US,en;q=0.5"});
console.log(newHeaders);
return newHeaders;
}
function updateListeners() {
if (!listener) listener = function (details) {
//console.log(details);
var header_map = {requestHeaders: details.requestHeaders};
if (details && details.url && details.requestHeaders && details.requestHeaders.length > 0)
{
header_map = {requestHeaders: replaceHeader("Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.37", details.requestHeaders)};
}
return header_map;
};
chrome.webRequest.onBeforeSendHeaders.addListener(listener, {"urls": ["" ]}, ["requestHeaders", "blocking", "extraHeaders"]);
}
var listener = null;
updateListeners();
这里默认填写的是ie10的ua和英文的Accept-Language
打包的话直接在插件管理页有一个打包按钮:
然后会生成一个.crx文件,发送给别人直接打开就可以用了。
https://www.cnblogs.com/liuxianan/p/chrome-plugin-develop.html.
https://crxdoc-zh.appspot.com/extensions/webRequest#event-onBeforeSendHeaders.
http://open.chrome.360.cn/extension_dev/messaging.html.