Chrome外掛初窺與實踐
某頁面獲取資訊時,需要驗證token判斷登陸資訊。因為某些原因,在測試過程中,測試人員需要採用手動注入token的方式完成登陸,嚴重影響工作效率。
為了避免影響原始專案,所以採用chrome外掛的方式,製作一個簡單的登陸頁面模擬實際登陸情況,並向原頁面插入token用作登陸資訊。
本文記錄了chrome外掛開發的簡單概念與外掛開發過程,方便以後深入學習chrome外掛的開發。
1、核心概念
(1)manifest.json
每一個chrome外掛都必須有一個JSON格式的清單檔案放在根目錄。下面是一些常見的配置項,其中manifest_version
、name
、version
為三個必填項。
{
// 必須
"manifest_version": 2, // 清單檔案的版本,必須為2
"name": "外掛名稱",
"version": "1.0.0",
// 推薦
"default_locale": "en",
"description": "外掛描述",
"icons": {...}, // 圖示
// 可選
"background":{
"page": "background.html" // 指定後臺頁面
"scripts": ["js/background.js"] // 指定後臺指令碼
"persistent": false // 推薦設定後臺指令碼為非持久
},
"browser_action": { // 工具欄圖示(或page_action)
"default_icon": "icon.png",
"default_title": "圖示標題",// 圖示懸停時的標題,可選
"default_popup": "popup.html"
},
"content_scripts": // 插入網頁的指令碼
[
{
"matches": ["http://*/*", "https://*/*"], // 匹配頁面url,<all_urls> 表示匹配所有地址
"js": ["content.js"], // 多個JS按順序注入
"css": ["css/custom.css"],
"run_at": "document_start"// 程式碼注入的時間,可選值: "document_start", "document_end", "document_idle",最後一個表示頁面空閒時,預設document_idle
},
{...}, // 可以配置多個規則
],
"permissions": // 許可權申請
[
"contextMenus", // 右鍵選單
"tabs", // 標籤
"notifications", // 通知
"webRequest", // web請求
"storage", // 外掛本地儲存
],
"default_locale": "zh_CN", // 預設語言
"devtools_page": "devtools.html"// devtools頁面入口,注意只能指向一個HTML檔案,不能是JS檔案
}
複製程式碼
(2)content_script
通過content_script
,我們可以向指定頁面注入JS或CSS。它與插入的頁面共享dom,即指令碼中使用的window物件與頁面中的window物件一致。
content_script
可以使用如下幾種chrome APIs
- i18n
- storage
- runtime(connect, getManifest, getURL, id, onConnect, onMessage, sendMessage)
(3)background
background
是一個執行與瀏覽器的後臺指令碼/頁面,與當前瀏覽頁面無關。在配置中,可以通過page
引入頁面,或通過scripts
引入JS檔案。
通過設定persistent
為false
,我們可以讓background
在需要時被載入,在空閒時被解除安裝,從而釋放系統資源。唯一保持後臺指令碼持續活動的情況是擴充套件使用chrome.webRequest API來阻止或修改網路請求。webRequest API與非永續性後臺頁面不相容。
(4)popup
popup
是點選瀏覽器工具欄上小圖示開啟的視窗,焦點離開頁面即關閉,可做臨時性互動。右鍵後點選“檢查”可開啟開發者工具進行除錯。
可以通過browser_action
與page_action
進行設定。browser_action
可作用於任何頁面,page_aciton
可作用與部分頁面。如vue tools外掛,當檢測到頁面沒有使用vue時,外掛圖示顯示為不可用。
2、專案實踐
(1)環境搭建
專案主要使用vue-cli
與vue-cli-plugin-chrome-ext
進行開發,element-ui
作為元件庫
1、安裝vue-cli
npm install -g @vue/cli
# OR
yarn global add @vue/cli
複製程式碼
2、初始化一個專案
vue create demo
複製程式碼
3、進入專案目錄,安裝vue-cli-plugin-chrome-ext
外掛。依次選擇外掛名稱、描述、版本號、使用js或ts
vue add vue-cli-plugin-chrome-ext
複製程式碼
4、清理檔案,刪除src/main.js
, src/components
, public/favicon.ico
和 public/index.html
,最終目錄結構
demo
├── README.md
├── babel.config.js
├── package.json
├── node_modules
│ ├── ...
├── src
│ ├── App.vue
│ ├── assets
│ │ └── logo.png
│ ├── manifest.development.json
│ ├── manifest.production.json
│ ├── options
│ │ ├── App
│ │ │ └── App.vue
│ │ ├── index.html
│ │ └── index.js
│ └── popup
│ ├── App
│ │ └── App.vue
│ ├── index.html
│ └── index.js
├── vue.config.js
└── yarn.lock
複製程式碼
(2)執行專案
執行npm run build-watch
,在根目錄生成dist
資料夾,在chrome擴充套件頁面chrome://extensions/,勾選開發者模式,選擇“載入已解壓的擴充套件程式”,選擇dist
資料夾,就可以新增擴充套件程式。新增好的外掛如下圖所示:
在位址列右側,也可以看到新增的外掛:
嘗試修改src/popup/App/App.vue
檔案
<template>
<div class="main_app">
<h1>Hello World!</h1>
</div>
</template>
複製程式碼
可以發現dist檔案被重新編譯,文字自動更新(注:如果修改了manifest.json,需要刪除外掛並重新安裝)
(3)開始開發
安裝element-ui
npm i element-ui -S
複製程式碼
為了減小檔案體積,按照element-ui
官網所示,採取按需引用的方式
npm install babel-plugin-component -D
複製程式碼
// babel.config.js
module.exports = {
// ...
plugins: [
[
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
]
]
}
複製程式碼
為popup
頁面引入需要使用的元件
// src/popup/index.js
// ...
import {Input,Button,Row} from "element-ui";
Vue.use(Input)
Vue.use(Button)
Vue.use(Row)
// ...
複製程式碼
使用元件完成頁面的繪製
// src/popup/App/App.vue
<template>
<div class="main">
<el-row>
<el-input v-model="form.mobile" type="number" placeholder="手機號"/>
</el-row>
<el-row>
<el-input v-model="form.vericode" type="text" placeholder="驗證碼">
<el-button slot="append" @click="sendVerifyCode">{{verifyText}}</el-button>
</el-input>
</el-row>
<el-row>
<el-button @click="login" type="primary">登陸</el-button>
</el-row>
</div>
</template>
<script>
export default {
name:'app',
data() {
return {
form: {
mobile: '',
vericode: '',
},
token:'',
verifyText:'獲取驗證碼',
}
},
methods: {
login() {}, // 登陸方法請按需實現
sendVerifyCode () {}, // 獲取驗證碼方法請按需實現
}
}
</script>
複製程式碼
如圖所示,此時popup
頁面繪製完成
現在,我們可以在popup
頁面輸入資料,發起請求並獲取token
,但是popup
頁面無法訪問原頁面,所以我們需要將token
傳遞給content
,由它將token
儲存在原頁面。
首先新建src/content/index.js
檔案,並在manifest.development.json
(生產環境在manifest.production.json
)中新增content
的配置
// src/manifest.deveploment.json
"content_scripts":
[
{
"matches": ["http://*/*", "https://*/*"], // 按需要修改匹配的地址
"js": ["js/content.js"],
"run_at": "document_start"
}
],
複製程式碼
修改vue.config.js
,新增content
打包設定
// vue.config.js
// 將content新增進chromeName即可
const chromeName = ["popup", "options", "content"];
複製程式碼
至此,content
的配置基本完成,下面需要實現的是popup
與content
之間的通訊
popup
頁面可以通過tabs.sendMessage
向content
傳遞資料。首先在manifest.development.json
中新增使用tabs
的許可權
// src/manifest.deveploment.json
{
// ...
"permissions":
[
"tabs"
],
}
複製程式碼
修改popup/App/App.vue
,向content
傳遞token
// src/popup/App/App.vue
// ...
login() {
this.token = '這是token'
this.sendMsgToContent()
},
sendMsgToContent() { //向content傳送資訊,讓conent在頁面的sessionStroage中儲存token
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
if (tabs.length !== 0) {
chrome.tabs.sendMessage(tabs[0].id, this.token, (response) => {
console.log(response)
});
}
});
}
複製程式碼
在content/index.js
中,接收token
值並儲存
// src/content/index.js
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
sessionStorage.clear()
sessionStorage.setItem('token',request)
sendResponse('收到請求');
});
複製程式碼
在頁面嘗試一下,寫入成功
(4)問題記錄
popup
的錯誤可以在視窗右鍵選擇‘檢查’
content
可以直接在頁面控制檯檢視
chrome擴充套件程式裡的錯誤
runtime
不加入許可權可以使用,加入許可權會報錯"Permission 'runtime' is unknown or URL pattern is malformed"
"Uncheked runtime.lastError.Could not establish connetcion.Receiving end does not exist"
。重新安裝外掛並重新整理頁面,基本就可以了。
(5)打包使用
執行npm run build
,生成dist
資料夾,擴充套件程式頁面chrome://extensions/選擇“打包擴充套件程式”,可生成crx檔案。安裝時,可以將crx檔案直接拖入擴充套件程式頁面進行安裝。(高版本chrome可能會提示“該擴充套件程式未列在 Chrome 網上應用店中...”,親測把crx的字尾改為zip,再安裝)
參考連結
- vue-cli3開發Chrome外掛實踐:juejin.im/post/5ceca3…(原文連結失效了,可百度標題)
- 一篇文章教你順利入門和開發chrome擴充套件程式juejin.im/post/5c135a…
- Chrome外掛(擴充套件)開發全攻略:www.cnblogs.com/liuxianan/p…
- Manifest配置文件:developer.chrome.com/extensions/…
- Chrome APIs:developer.chrome.com/extensions/…