navigator.sendBeacon で Content-Type を指定したい

計測用のリクエストみたいな小さいリクエストを投げるためのnavigator.sendBeaconっていうAPIがあって、fetchXHRと違ってunload時でもリクエストが送信されるのが保証されるのが売りらしい。メジャーなブラウザには実装されつつある。

Navigator.sendBeacon() - Web APIs | MDN

デフォルトだとContentTypetext/plainなんだけど、application/jsonとかに変更したいということはけっこうあると思う。その場合Blobtypeに指定すればいいらしい。

const body = { name: 'foo' };
const blob = new Blob([JSON.stringify(body)], { type: 'application/json' });
navigator.sendBeacon('/log', blob);

これで Firefox 63 はいけたんだけど、Chrome 70 だと以下のようなエラーで送れなかった。

Uncaught DOMException: Failed to execute 'sendBeacon' on 'Navigator': sendBeacon() with a Blob whose type is not any of the CORS-safelisted values for the Content-Type request header is disabled temporarily. See http://crbug.com/490015 for details.

CORS の問題で一時的に無効になってるらしい。Same Originなのに...。元々 preflight が飛ばないapplication/x-www-form-urlencodedだと大丈夫そう。

Firefox は Cross Origin の場合はちゃんと preflight 飛ばして送信してた。