我是如何开发我的第一个Chrome插件的
自己钓鱼的时候发现看盗版小说总是出现不伦不类的广告页面。我发现公共场所不适合。有没有办法去除广告?不可能每次都点击删除按钮,但Chrome浏览器插件可以完美。来实现这个小小的要求。
主要结构
Chrome浏览器插件主要由几个重要文件组成:

目录
上图其实就是这个插件。我们可以看到Chrome浏览器插件其实就是一个页??面。我们没有压力开始使用UI,最重要的是manifest.json文件。这就是整个插件的配置
{
//manifest文件的版本,这个必须写而且必须是2
“清单版本”:2,
//插件名称
“名称”:”演示”,
//插件版本
“版本”:“1.0.0”,
//插件说明
“description”:”简单的Chrome扩展演示”,
//图标,如果你很懒并且将它们全部使用一种尺寸,那就没问题了。
“图标”:
{
“16”:”img/icon.png”,
“48”:”img/icon.png”,
“128”:”img/icon.png”
},
//永远常驻的后台JS或后台页面
“背景”:
{
//2种方式指定,如果指定JS则自动生成后台页面
“页面”:”背景.html”
//“脚本”:[“js/background.js”]
},
//浏览器右上角的图标设置,browseraction,pageaction,app三者必须选其一
“浏览器操作”:
{
“defaulticon”:”img/icon.png”,
//按住图标时的标题,可选
“defaulttitle”:”这是一个示例Chrome插件”,
“defaultpopup”:“popup.html”
},
//仅在某些页面打开时出现的图标
/*“页面动作”:
{
“defaulticon”:”img/icon.png”,
“defaulttitle”:”我是pageAction”,
“defaultpopup”:“popup.html”
},*/
//必须直接注入页面的JS
“内容脚本”:
[
{
//”匹配”:[“http://*/*”,”https://*/*”],
//””表示匹配所有地址
“火柴”:[””],
//多个JS依次注入
“js”:[“js/jquery-1.8.3.js”,”js/content-script.js”],
//你可以随便注入JS,但是你要小心CSS,因为一不小心就会影响全局样式。
“css”:[“css/custom.css”],
//代码注入时间,可选值:
//”文档开始”,”文档结束”,”文档标题”,
//最后一项表示当页面处于非活动状态时,默认文档
“runat”:”文档开始”
},
//这只是为了说明content-script可以配置多个规则
{
“匹配”:[“*://*/*.png”、“*://*/*.jpg”、“*://*/*.gif”、“*://*/*”。bmp”],
“js”:[“js/show-image-content-size.js”]
}
],
//访问请求
“权限”:
[
“contextMenus”,//右键菜单
“标签”,//标签
“通知”,//通知
“webRequest”,//网络请求
“网络请求阻止”,
“storage”,//插件本地存储
“http://*/*”,//可通过executeScript或insertCSS访问的站点
“https://*/*”//可以通过executeScript发送或者insertCSS访问的网站
],
//常规页面可直接访问的插件资源列表。如果不设置,则无法直接访问。
“webaccessibleresources”:[“js/inject.js”],
//插件网站,这个很重要,不要浪费这个免费的广告空间
“homepageurl”:”https://www.baidu.com”,
//覆盖默认浏览器页面
“铬欧洲覆盖”:
{
//覆盖浏览器默认的新标签页
“newtab”:”newtab.html”
},
//Chrome40之前如何编写插件配置页面
“optionspage”:”options.html”,
//Chrome40之后插件配置页面怎么写。如果两者都写的话,新版本的Chrome只会识别后面的一个。
“选项”:
{
“页面”:”选项.html”,
//添加一些默认样式,推荐
“chromestyle”:正确,
//默认值为false,表示以嵌入方式打开选项页面,true表示在新选项卡中打开选项页面。
“openintab”:正确
},
//在地址栏注册一个关键字,提供搜索建议,只能设置一个关键字
“omnibox”:{“keyword”:”go”},
//默认语言
“defaultlocale”:”zhCN”,
//devtools页面入口,注意只能指向HTML文件,不能指向JS文件
“devtoolspage”:“devtools.html”
}
以上是manifest.json的一些配置信息。如果您需要详细的配置信息,可以查看developer.chrome.com。不过目前按照上面的要求开发插件时,不需要那么多的配置信息:
{
“清单版本”:2,
“名称”:“bookcrx”,
“版本”:“1.0.0”,
“description”:”简单的Chrome扩展程序,用于在线阅读小说并删除广告”,
“图标”:{
“16”:”img/icon.png”,
“48”:”img/icon.png”,
“128”:”img/icon.png”
},
“背景”:{
“脚本”:[“js/main.js”]
},
“内容脚本”:[
{
“matches”:[“http://m.biqu6.cc/*”]//匹配新站点
}
]
}
新建一个插件目录,并新建一个与配置信息对应的文件。

Main.js是执行代码逻辑的文件。我又整理了一下需求:去掉网站上的广告。由于这是一个新网站,我选择粗鲁地删除页面上的所有img元素。代码也很简单。
document.addEventListener(‘DOMContentLoaded’,function(){
console.log(‘我被处决了!’);
Array.from(document.querySelectorAll(‘img’)).forEach(ele>{
ele.remove();
})
});
安装
开发完成后,出现安装问题:“点击chrome右上角三个点->更多工具->扩展”或者直接访问“chrome://extensions/address”

“启用开发者模式”后,您可以看到三个按钮选项。

点击【加载解压扩展名】直接加载图书分类目录

然后我们就可以看到效果了
抱歉,我无法使用该效果,它会被黑
现在您可以不受广告打扰地钓鱼了。
替代方案
上面实现了一个基本的插件,但是这个插件只能在新站点上使用。如果你碰其他盗版小说网站,那也是没有用的,因为目前只配置了一个网站。
“内容脚本”:[
{
“匹配”:[“http://m.biqu6.cc/*”]
}
]
我们可以通过配置选项页面来动态配置多个站点,这些站点必须在manifest.j中配置son文件中的options.html页面
“optionspage”:”options.html”,
“选项”:{
“页面”:”选项.html”,
“chromestyle”:正确,
“openintab”:正确
},
然后在根目录下新建options.html
html>
htmllang”en”>
主要>
元字符集“UTF-8”>
元名称“viewport”内容“widthdevice-width,initial-scale1.0”>
标题>替代标题>
主要>
正文>
h1>替代sh1>
inputid”输入”类型”文本”占位符”输入网站”>
Buttonid”btn”>添加按钮>
scriptrc”js/options.js”>脚本>
正文>
html>
然后在chrome://extensions/地址中找到插件并点击更新;点击浏览器右侧的扩展图标可以看到【Options】,点击进入我们自己编写的options.html页面

创建新的options.js
;(函数(窗口,文档){
constSKEY’已预订’;
document.querySelector(‘#btn’).onclickfunction(){
constvaldocument.querySelectorAll(‘input’)[0].value
控制台.log(选项)
//获取背景结束
constpagechrome.extension.getBackgroundPage()
page.getStore(SKEY).then(site>{
控制台.log(站点)
if(Array.isArray(站点)){
站点.push(选择);
page.setStore(SKEY,站点);
alert(‘添加成功!’)
}其他{
page.setStore(SKEY,[val]);
alert(‘添加成功!’)
}
})
}
})(窗口,文档)
内容脚本
contentscripts选项是内容脚本,是在配置页面加载时运行的脚本。这里逻辑被移至contentscripts.js。必须首先配置Manifest.json。
“内容脚本”:[
{
“火柴”:[””],
“js”:[
“js/contentscripts.js”
],
“runat”:”文档结束”
}
],
创建新的contentscripts.js
console.log(‘我被处决了!’);
//清除存储()
getStore(‘预订’).then(站点>{
控制台.log(站点);
if(!Array.isArray(sites))return;
站点.forEach(站点>{
if(location.href.includes(site)){
主要的();
}
})
})
函数主(){
const$imgsdocument.querySelectorAll(‘img’);
const$bingodocument.querySelectorAll(‘bingo’);
const$objectdocument.querySelectorAll(‘object’);
Array.from($imgs).forEach(ele>{
ele.remove();
})
Array.from($bingo).forEach(ele>{
ele.remove();
})
数组.from($object).forEach(ele>{
ele.remove();
})
}
函数setStore(键,值){
returnnewPromise(解决>
chrome.storage.local.set({[key]:value},解析)
);
}
函数getStore(key){
returnnewPromise(解决>{
chrome.storage.local.get(key,item>resolve(item[key]));
});
}
函数clearStore(){
returnnewPromise(解决>{
chrome.storage.local.clear(()>resolve());
});
}
这里我们使用chrome.store来存储URL配置。使用此选项需要在manifest.json文件中配置权限。
“权限”:[
“贮存”
]
》注意:》chrome.storage中存储的数据无法在开发者调试工具中查看。这里我用代码来清理数据。
盒
单击[包扩展]按钮

选择要打包的目录并生成.crx文件,但必须发布到GoogleApps才能使用。

总结
插件只是简单的使用,里面还有更详细的知识点,可以帮助插件实现更多的功能。这次我找到了自己生活中的一个需求点,并用技术来解决它。后来我也尝试用vue重建它,源代码在这里。
》注意:》使用CDN时,加载器会出现如下错误

需要在manifest.json中添加字段
“contentsecuritypolicy”:”style-src’self”unsafe-inline’https://cdn.jsdelivr.net;script-src’self”unsafe-eval’https://cdn.jsdelivr.net;object-src’自己’;”