Chrome游览器插件开发
- 最近在尝试开发一个谷歌游览器插件,遇到了不少问题,在这里做一个简单的记录。
- 插件代码上传到了Gitee,点击仓库地址可进行访问。其中插件的配置文件在public文件夹下面。
配置文件manifest.json
{
"name": "HEU官网小助手",
"description" : "HEU官网小助手",
"version": "1.0.0",
"manifest_version": 2,
"icons": {
"16": "image/HEU_icon_16.jpg",
"32": "image/HEU_icon_32.jpg",
"64": "image/HEU_icon_64.jpg",
"128": "image/HEU_icon_128.jpg"
},
"browser_action": {
"default_popup": "index.html",
"default_icon": "image/HEU_icon_16.jpg"
},
"content_scripts": [
{
"matches": ["http://*.hrbeu.edu.cn/*"],
"js": ["Chrome/chromeIndex.js"],
"css": [],
"run_at": "document_end"
}
],
"homepage_url": "https://www.baidu.com",
"web_accessible_resources": ["Chrome/*", "assets/*", "image/*"]
}
Chrome插件图标无法显示
- 我最开始按照网上教程写配置文件,发现怎样都无法显示图标,为此苦恼了很长时间。
- 后来发现这是因为图片格式的问题,我一开始使用的是
.jpg
格式的文件,但它无法显示,后来改成.png
格式的文件后就正常了。
向页面中注入JS/CSS文件(方法1)
- 有两种方式,一种是写在配置文件中,游览器自动帮我们完成注入操作:
"content_scripts": [{
"matches": ["http://*.hrbeu.edu.cn/*"],
"js": ["Chrome/chromeIndex.js"],
"css": [],
"run_at": "document_end"
}],
- 如上所示,我们可以在
content_scripts
数组中定义注入规则,matches
用来匹配网址,run_at
用来设定注入的时机。 - 但上面这种注入方式有个问题,那就是它和页面中原来的JS环境是相互隔离的(据说是这样的),所以如果涉及到要复写原本网页函数等操作,这种注入方式就不行。
向页面中注入JS/CSS文件(方法2)
- 另外一种注入方式就是想dom元素中插入
script
和link
标签,让他们通过请求的方式注入文件。 - 先通过第一种方式将下列代码注入到页面中,当它运行起来后,就会自动把对应的文件引入到页面中。
[
'https://unpkg.com/element-plus/lib/theme-chalk/index.css',
].forEach(url => {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = url;
document.head.appendChild(link);
});
[
'/assets/vendor.js',
'/assets/index.js'
].forEach(jsPath => {
const script = document.createElement('script');
script.setAttribute('type', 'module');
script.src = chrome.extension.getURL(jsPath);
document.head.appendChild(script);
})
- 这种方法需要让网页访问插件的资源,而这默认情况下是不允许的,需要我们在配置文件中指明允许访问的资源,如下示例所示:
"web_accessible_resources": ["Chrome/*", "assets/*", "image/*"]
- 这种注入方式还有一个问题,就是如果你注入JS/CSS文件中以存在相对路径的方式请求插件资源,那么是无法正确请求到资源的,因为该请求会被发送到当前网页所在的服务器,而不是插件。
- 我在开发插件的时候就遇到这个问题,字体资源没法正确响应请求而被加载,导致各种图标全部无法显示,因为我使用的是
vue3 + element-plus
开发的,在CDN上就有对于的css文件,所以我选择请求网络上的资源,而不是插件中的资源来解决这个问题。 - 当然如果只能请求插件中的资源,那么我们只能手动读入文件到内存,然后替换掉那些相对地址,将它们变成指向插件资源的绝对地址,具体可以参考下面的代码:
script.src = chrome.extension.getURL(jsPath);