通信を垂れ流してなにかするChrome拡張


## やること
Chromeで発生する通信を捕まえて、なにかをするための準備をする。

## 構成
適当なフォルダをつくり、Chrome拡張に必要なファイルを揃える。

```javascript:構成
NetworkWatcher
 ┃
 ┣━ manifest.json  // いろいろ設定を書く
 ┃
 ┣━ background.js  // 通信を捕まえる処理を書く
 ┃
 ┣━ contents.js    // ページ上の処理を書く
 ┃
 ┗━ icon.png       // アイコン画像
```

## manifest.json

`manifest.json`に必要な情報を書く。
必要最低限の記述のみ記載するので、その他の設定は[Manifest File Format - Google Chrome](https://developer.chrome.com/extensions/manifest)へ。

```json:manifest.json
{
  "manifest_version": 2,
  "name": "NetworkWatcher",
  "version": "0.0.0",
  "icons": {
    "128": "icon.png"
  },
  "permissions": [
    "*://*/*/",
    "webRequest",
    "tabs"
  ],
  "background": {
    "scripts": [
      "background.js"
    ]
  },
  "content_scripts": [{
    "matches": ["*://*/*"],
    "js": ["content.js"],
    "run_at": "document_start"
  }]
}
```


とりあえずすべての通信をキャッチしたいので、`webRequest`（通信を拾うAPI）と`*://*/*/`（全domain）を `permissions`に指定。
`tabs`は後述。

また、最終的にページ側で通信をキャッチさせたいので、`content_scripts`の`run_at`には`document_start`を指定しておく。
詳細は[Content Scripts - Google Chrome](https://developer.chrome.com/extensions/content_scripts)へ。

## 通信を拾う

`webRequest`APIをつかって通信をキャッチする処理を`background.js`書く。

```javascript:background.js
chrome.webRequest.onBeforeRequest.addListener(
  function (details) {
    console.log(details.url);
  },
  {urls: ['<all_urls>']},
  []
);
```

これだけでbackground pageに通信内容がコンソール出力されるようになる。

## 拡張を読み込む

上記の状態で、実際にChromeに拡張を読み込ませてみる。
Chromeで[chrome://extensions/](chrome://extensions/)にアクセスし、「デベロッパーモード」にチェックを入れて「パッケージ化されていない拡張機能を読み込む...」を押す。

![Kobito.lMVw5C.png](https://qiita-image-store.s3.amazonaws.com/0/53664/b5346659-dc18-97b6-6d06-0b2c1c95d3d6.png "Kobito.lMVw5C.png")

はじめにつくったフォルダを選択すると、

![Kobito.JyoQgc.png](https://qiita-image-store.s3.amazonaws.com/0/53664/3763d86b-ad74-4e6d-1c68-2c7ce68de3d1.png "Kobito.JyoQgc.png")

拡張が読み込まれる。

![Kobito.HojMF3.png](https://qiita-image-store.s3.amazonaws.com/0/53664/2540e3a5-a966-71c4-161d-c54f709eed0a.png "Kobito.HojMF3.png")


「バックグラウンド ページ」を押すと別窓でコンソールが立ち上がるので、適当なサイトにアクセスすると動作確認ができる。

↓Googleにアクセスしたときのログ。

![Kobito.xINWaf.png](https://qiita-image-store.s3.amazonaws.com/0/53664/11c11a55-5f02-adc7-bd4f-c417182062c8.png "Kobito.xINWaf.png")


## データをページ側に渡す

background pageに吐き出されているログをページ側で扱いたいので、その部分のデータの受け渡し処理を追記する。
データの受け渡しには`tabs`APIをつかう。

```javascript:background.js
chrome.webRequest.onBeforeRequest.addListener(
  function (details) {
    console.log(details.url);
    // 現在のタブを取得する
    chrome.tabs.query({
      active: true,
      windowId: chrome.windows.WINDOW_ID_CURRENT
    }, function (result) {
      var currentTab = result.shift();
      // 取得したタブに対してメッセージを送る
      chrome.tabs.sendMessage(currentTab.id, details, function() {});
    });
  },
  {urls: ['<all_urls>']},
  []
);
```


```javascript:content.js
// メッセージを受け取る
chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) {
  console.log(message);
});
```

## 拡張を更新する

jsを修正したら、[chrome://extensions/](chrome://extensions/)でリロードするだけで更新される。
![Kobito.IQUSnL.png](https://qiita-image-store.s3.amazonaws.com/0/53664/dcaccd62-b4af-81fa-2c2b-f73bdfd9da03.png "Kobito.IQUSnL.png")

↓こんな感じ
![Kobito.XqiUnO.png](https://qiita-image-store.s3.amazonaws.com/0/53664/cd18ddc7-f615-558d-ee65-41d3b5b226bc.png "Kobito.XqiUnO.png")

## Next...

とりあえず通信を拾えるようになったので、このデータを使ってなにかしたい。