ファイルダウンロードできるChrome拡張(Chrome Extension)をつくる
Chrome 拡張(Chrome Extension)でファイルダウンロードさせたい。
実装は簡単なんですが、JS を実行させるまでハマったのでメモ。
なお、「自作のChrome拡張を使うにはどうしたらいいの?」っていうのは書いてないです。
そこはクリアして書き始めた人向け。
Chrome 拡張の chrome.downloads を使う
Chrome拡張の設定ファイルであるmanifest.json
のpermission
に"donwloads"
を設定するだけで使える。
のですが、ページ表示でcontent_scripts
から実行される JavaScript に登録するだけでは使えないのでハマりました。
chrome.downloads
を利用できるのはバックグラウンドで動作する JavaScript です。
ページ側で動作するcontent_scripts
からは直接使えないので、バックグラウンド側に情報を渡して動作させます。
ちなみに以前は Google Chrome
派でしたが、Chromium版Edge
の垂直タブが便利すぎて乗り換えました。
Chromium 版 Edge でも chrome 拡張がそのまま使えます。
今回の動作確認も Chromium版Edge
で行っています。
必要なもの
chrome 拡張ではmanifest.json
を書く必要があり、他は普通の JavaScript や HTML、CSS と一緒です。
今回は chrome.downloads
を利用したいので、フロント用とバックグラウンド用の 2 つの JavaScript ファイルを用意します。
ページ表示のタイミングで自動で動き、UIがないのでHTML、CSSは不要です。
- manifest.json: chrome 拡張の定義
- main.js: フロントで実行される JavaScript
- background.js: フロントから呼び出される JavaScript
があれば動かせます。
開発環境の準備
VScode がおすすめですが、テキストエディタがあれば開発できます。
github 上のサンプル集からキーワード検索・コードをコピペして改造していくのが良いと思います。
https://github.com/GoogleChrome/chrome-extensions-samples にあるので、検索しやすいようにローカルに clone しておきましょう。
# 公式サンプルをよく参照するので、探しやすいようにcloneしておく
git clone https://github.com/GoogleChrome/chrome-extensions-samples.git
manifest.json の作成
公式のWelcome to Manifest V3に情報がありますが、正直欲しい情報を探しにくい・・・
manifest_version
の 2 と 3 では項目名が違ったりするので、使うサンプルのバージョンにも気をつけてください。
{
"manifest_version": 3,
"name": "myDownloader",
"version": "0.0.1",
"permissions": ["downloads"], // chrome.donwolad APIを利用する場合に必須
"background": {
"matches": ["https://bitto.jp/*"], // 開いたページのURLがマッチする場合に実行
"service_worker": "background.js"
},
"content_scripts": [
{
"matches": ["https://bitto.jp/*"], // 開いたページのURLがマッチする場合に実行
"js": ["main.js"]
}
]
}
permissions
には downloads
を設定しておきます。
main.js の作成
chrome 拡張を仕込みたいページ側で動作する JavaScript です。
ページを解析して対象のダウンロード URL を探す役割をします。
URL を探しますが、こちらからは直接chrome.downloads
を呼び出すことができません。
chrome.runtime.sendMessage
を介して後述のbackground.js
にダウンロード情報を渡す必要があります。
今回はシンプルに、ページ表示のタイミングでダウンロードを開始する例を作ります。
chrome.runtime.sendMessage
では任意のオブジェクトを送信できます。
URL からダウンロードするだけなら、直接文字列で渡してもいいでしょう。
// background.jsを呼び出す関数
function startDl() {
chrome.runtime.sendMessage({ url: "https://bitto.jp/cat.png" })
}
// 関数をwindow.onLoadのタイミングで実行させる
window.addEventListener('load', startDl)
background.js の作成
ただ DOM をいじるだけならcontent_scripts
だけで良いのですが、chrome.downloads
は manifest.json
の permissions
で許可した上でバックグランドでしか使えません。
これが分かるまで main.js
側でchrome.downloads
が触れず、ちょっとハマりました。
保存先のダウンロードファイル名を変更するには、chrome.downloads.onDeterminingFilename
を使います。
リスナは多重登録できないので、1つの関数でファイル名を解決させる必要があります。
保存先のパスはディレクトリ名も含められるので、サイトごとにファイルをまとめることもできます。
chrome.downloads.download
がダウンロード ID を返すので、それに紐付いたファイル名で変更できます。
// main.jsから呼び出される
let fileNames = {}
chrome.runtime.onMessage.addListener(function (msg) {
const { url } = msg
chrome.downloads.download({ url }).then(id => {
fileNames[id] = "neko.png" // idとファイル名を関連付け
})
})
// ファイル名変更のためリスナを追加(1回だけ登録、変更しなくていいなら要らない)
chrome.downloads.onDeterminingFilename.addListener((ev, __suggest) => {
const filename = fileNames[ev.id] // ダウンロードIDからファイル名を解決
delete fileNames[ev.id]
__suggest({ filename })
})
動作サンプル
NEKOHA YOSHIDA / chromeExtensionSample_downloads - GitLab
まとめ
manifest.json
さえ書いてしまえばあとは普通のJavaScriptです。
思ってたより簡単に試すことができました!
参考サイト
Chrome Extensionを作ってみよう
https://np-complete.gitbook.io/chrome-extension/chrome-extensionwottemiyou
Welcome to Manifest V3 - ChromeDevelopers
https://developer.chrome.com/docs/extensions/mv3/intro/
GoogleChrome/chrome-extensions-sample - GitHub
https://github.com/GoogleChrome/chrome-extensions-samples