Chrome拡張機能からダウンロードを開始できても、希望する場所へ保存できたとは限りません。保存ダイアログで待機していたり、ほかの拡張の処理によって名前が変わったりすることがあります。
保存処理は「開始」「完了」「保存先の確認」を分けて記録すると、どこで止まったかを調べやすくなります。
最初に保存オプションとChrome側を調べる
download()に渡したfilename、saveAs、conflictActionを確認します。保存場所の確認設定、管理ポリシー、警告、他の拡張機能も切り分けます。制作時にはsaveAs: falseでもダイアログで待機する環境がありましたが、すべてのChrome環境で同じ条件になるという一般仕様にはしません。
chrome://settings/downloadsを利用者が確認できる導線を用意すると便利です。設定変更は他サイトの保存にも影響するため、その点も伝えます。公式downloads APIと照らし合わせ、最小の保存テストで再現を確認します。
完了待ちに終了条件を付ける
次は、拡張の設定ページなど、処理中も開いている画面で使う完了待ちの例です。イベント登録後に現在状態も検索し、すでに終わったダウンロードを取りこぼさないようにします。
function waitForDownload(downloadId, timeoutMs = 60000) {
return new Promise((resolve, reject) => {
let settled = false;
let timer;
const finish = (error, item) => {
if (settled) return;
settled = true;
clearTimeout(timer);
chrome.downloads.onChanged.removeListener(listener);
if (error) reject(error); else resolve(item);
};
const inspect = async () => {
try {
const [item] = await chrome.downloads.search({ id: downloadId });
if (!item) return finish(new Error("Download record not found"));
if (item.state === "complete") finish(null, item);
if (item.state === "interrupted") finish(new Error(item.error || "Interrupted"));
} catch (error) { finish(error); }
};
const listener = delta => {
if (delta.id === downloadId && delta.state) void inspect();
};
timer = setTimeout(() => finish(new Error("Download completion timed out")), timeoutMs);
chrome.downloads.onChanged.addListener(listener);
void inspect();
});
}
Manifest V3のService Workerは停止・再起動します。長い保存処理をメモリ上のPromiseとタイマーだけに任せず、downloadIdと業務上の保存状態を永続化し、イベント受信時や画面再表示時に照合します。
実際のファイル名を照合する
downloads.searchのfilenameは実際の保存パスです。要求した拡張子・サブフォルダーと照合し、不一致なら「完了」と「希望した保存先への保存」を別の状態として表示します。uniquifyで付く連番など、許容する差も先に決めておきます。
制作時のChrome for Testingでは、他拡張のonDeterminingFilenameリスナーが関与すると、data URLの既定名へ変わる事例が観測されました。リスナーが存在すれば常に壊れると断定せず、最小の再現用拡張と組み合わせ、片方ずつ無効にして原因を絞ります。
保存テストは専用の小さなファイルで行います。後片付けも、そのテストで発行したdownloadIdのファイルに限定します。異なるパスになったからといって、既存ファイルを自動削除する設計にはしません。
保存済みの記録とファイルの存在は別にする
利用者が後でファイルを移動・削除しても、拡張の保存記録は残ります。DownloadItem.existsや再検索の結果を確認し、必要なら利用者が選択したディレクトリで確認します。
制作時にはfile://のディレクトリ表示を取得する方法も試されましたが、表示HTMLは安定したAPIではなく、権限やブラウザー版にも依存します。ファイル一覧を必要とする製品機能では、File System Access APIなど、アクセス許可と対象範囲が明確な方法を検討します。
