Chrome拡張でリクエストの簡易フィルタリング

# 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の配列なので、コマンドで生成するのが楽でいいかもしれないです。
配列の配列でホワイトリスト/ブラックリストの正規表現を格納しているので、ログを採取してから優先順位をつければ応答も改善できそうです。