風柳メモ

ソフトウェア・プログラミング関連の覚書が中心。

Chrome拡張機能にてシークレットウィンドウとbackgroundとのメッセージ送受信時の注意


ハマったよ……

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 を分ける羽目に……せっかく共通化していたのに(苦笑)。