ハマったよ……
Twitter メディアローダ
furyu.hatenablog.com
にて、Google Chrome のシークレット ウィンドウ上で実行すると、ファイルダウンロード時に
失敗 - ファイルがありません
シークレット ウィンドウでだけ発生するという訳の分からない状態だったので、途方に暮れていたのだが……。
何が起こっていたのか?
background → content_scripts に、ZIP化したコンテンツの Blob URL を sendResponse() で送信する仕組みにしていたのだが、なぜか受け取った content_scripts 側(シークレット ウィンドウ)で、その Blob URL にアクセスできない状態(404発生)になっていた。
原因
Manifest - Incognito - Google Chromeによると、manifest.json に指定できる "incognito" キーについて、シークレット ウィンドウ(匿名タブ)で動かせる拡張機能では"spanning"もしくは"split"が指定でき、
- "spanning"(デフォルト)
→ 匿名タブ(ウィンドウ)と、その他の(一つのプロセス上で共有される)コンテキスト(これにはoptions_uiやbackgroundページも含む)とがあり、匿名タブは共有プロセスにアクセスできない - "split"
→匿名タブ(と対応する background ページ)は、(匿名でないタブからみて)独立したプロセス上で動作し、メッセージ等のリソースもプロセス内のコンテキストのもののみを参照できる(それ以外のコンテキストとはやり取りできない)
対応しているbackgroundとは共通のリソースにアクセスできると思われる
となっているように読める。
英語の解読に自信はないので、読み取り間違っているかもしれない。その場合はご指摘を……。
なので、manifest.json で明示していなかったために "spanning" モードで動いていた本拡張機能では、background で作成した Blob URL に匿名タブからアクセスできなかったのだと思われる。
対策
manifest.json に
, "incognito" : "split"
を追加。
念のため、backgroundでの ZIP 化を無効化するオプションも付けておいた
副作用
Firefox では、"incognito" キーはサポートしているが、選択肢として "split" がサポートされていない。
このため、manifest.json を Chrome と共通にしていると、アドオン登録の検証時に
"/incognito" should be equal to one of the allowed values
エラー: Your JSON file could not be parsed.
というエラーが発生し、撥ねられてしまう。
やむを得ず、Chrome と Firefox とで manifest.json を分ける羽目に……せっかく共通化していたのに(苦笑)。