Chrome拡張実装(リクエストのフィルタリング)
初めてChrome拡張を実装してみましたので、投稿してみます。
何か意見・指摘などあれば是非よろしくお願い致します。
目的
バックグラウンドページを使い、リクエストのフィルタリングをしてみたかった。
環境
- Windows 10 Home
- Google Chrome 96.0.4664.45
- javascript
フォルダ構成
├─manifest.json
├─jquery
│ └─3.6.0
│ └─min.js
├─background.js
├─blacklist
│ └─ block.js
└─whitelist
└─ pass.js
各ファイルの内容
*jQueryはもちろん除きます。
manifest.json
{
"name": "Sample Extension Ishy",
"version": "1.0.0",
"manifest_version": 2,
"description": "Sample Chrome Extension",
"permissions": [
"<all_urls>",
"webRequest",
"webRequestBlocking"
],
"background": {
"scripts": [
"whitelist/pass.js",
"blacklist/block.js",
"jquery/3.6.0/min.js",
"background.js"
],
"persistent": true
}
}
background.js
if(chrome.webRequest) {
function translateToRegex(lists) {
var regexes = new Array();
lists.forEach(function(map) {
var obj = new Array();
obj.push(map[0]);
obj.push(new RegExp(map[1].join("|")));
this.push(obj);
}, regexes);
return regexes;
}
function getWhiteLists() {
var lists = [
[ "whites", whites ]
];
return translateToRegex(lists);
}
function getBlackLists() {
var regexes = new Array();
var lists = [
[ "blacks", blacks ]
];
return translateToRegex(lists);
}
function getDetailMsg(details, msg) {
var shortUrl = details.url.substring(0, 120);
var now = new Date();
//var header = now.toISOString() + " " + details.initiator;
var header = now.toTimeString().substring(0, 8) + " " + details.initiator;
return header + " #" + msg + " " + shortUrl;
}
function applyFilterRegex(details, filters, msg) {
for(var i=0; i<filters.length; i++) {
var filter = filters[i];
if(filter[1].test(details.url)) {
var detailMsg = getDetailMsg(details, msg + "(" + filter[0] + ")");
console.debug(detailMsg);
return true;
}
}
return false;
}
var whiteRegexes = getWhiteLists();
var blackRegexes = getBlackLists();
chrome.webRequest.onBeforeRequest.addListener(
function(details) {
var result = applyFilterRegex(details, whiteRegexes, "Approve");
if(result) {
return { cancel: false };
}
var result = applyFilterRegex(details, blackRegexes, "Block");
if(result) {
return { cancel: true };
}
var detailMsg = getDetailMsg(details, "Pass");
console.info(detailMsg);
return { cancel: false };
},
{
urls: ['<all_urls>']
},
["blocking"]
);
} else {
console.error("webRequest : not active" );
}
whitelist/pass.js
var whites = [
'youtube.com/',
'google.com/',
'google.co.jp/',
'googlevideo'
];
blacklist/block.js
var blacks = [
'twitter',
'facebook',
'fc2',
'ytimg'
];
コンソールの出力例
background.js:68 20:46:22 https://qiita.com #Pass https://qiita.com/api/preview
background.js:68 20:46:23 https://qiita.com #Pass https://qiita.com/graphql
background.js:47 20:47:00 undefined #Approve(whites) https://www.youtube.com/?gl=JP&tab=r11
background.js:47 20:47:00 https://www.youtube.com #Block(blacks) https://i.ytimg.com/generate_204
background.js:47 20:47:01 https://www.youtube.com #Approve(whites) https://www.youtube.com/getDatasyncIdsEndpoint
結果
まあまあ予定通りのものができました。
フィルタ用のキーワードはjavascriptの配列なので、コマンドで生成するのが楽でいいかもしれないです。
配列の配列でホワイトリスト/ブラックリストの正規表現を格納しているので、ログを採取してから優先順位をつければ応答も改善できそうです。