Chrome 拡張機能の CORS エラーを回避(Manifest V3)


とても嬉しいので記事にする

CORS = オリジン間リソース共有(Cross-Origin Resource Sharing)

ざっくり言うと、ページに使用するソースは自分とは異なるオリジン (ドメイン、プロトコル、ポート番号) から参照する事はできませんよ、というもの。
詳細は他に良い記事が沢山あるので割愛します。

参考:なんとなく CORS がわかる...はもう終わりにする。

で、本題。Chrome 拡張機能のマニフェストバージョンを3にすると、以前はできなかった CORS 回避が簡単にできるようになりました。

これの何が嬉しいのかって言うと、『拡張機能のbackground.jsなどから外部の REST API を叩こうとすると、API 側がAccess-Control-Allow-Originヘッダーを返すようにしていない限り、CORS エラーで取得できなかった』り、『API が JSONP に対応していればそれを使って取得』していたのが解決できる、と。
こりゃ嬉しい。

もしかしたら、私が知らなかっただけで出来ていたのかもしれませんが、散々ググった結果、出来ないとの結論に落ち着いていたので、簡単にできた時は嬉しかったんですね。

あ、Chrome 拡張機能も Javascript も、素人もいいとこなので、勘違いしていたらすみません。
なお、その際は、この記事は自動的に黒歴史となる予定です。

やり方

manifest.jsonのバージョンを3にした上で、"host_permissions"を加えるだけです。

manifest.json

"manifest_version": 3,
"host_permissions": [
    "https://api-address/"
]

あとはお好きにデータを引っ張ってきましょう。
ただし、V3 にすると、background.jsservice_workerで指定した JS)ではxmlHttpRequestが使用できない為、fetchを使いましょう。

background.js
var url = "https://api-address/query";

fetch(url)
    .then(function (res) {
        return res.json(); // フェッチしたデータを JSON 形式に変換
    })
    .then(function (jsonData) {
            console.log(jsonData); // JSON へ変換されたデータをコンソールに表示
        })
    })

これで、CORS 対応していない API でもブッ叩く事が出来るようになります。

『郵便番号検索 API』あたりが CORS エラーを返してくれると思うので、試してみて下さい。

まとめ

JSONP とか使わずに API レスポンスが取れて、とても嬉しいです。
ただ、実現する為にはマニフェストバージョンを3にする必要があるため、既存の拡張機能に実装するのは修正が面倒かもしれませんね。

おまけ

実際に V3 で作った拡張機能は以下の物になります。ご参考までに。