User-Agent Client Hints のメモ
従来の User-Agent の問題
- 現在の UA は多くの情報が入っており、それをデフォルトで送信することはプライバシーの観点からやめたい
- パースが複雑になるので、バグの原因となりやすい
User-Agent Client Hints
従来の UA と同じ情報にアクセスにできるようにしつつ、プライバシーの保護や、よりパースをしやすく整備した。 サーバーサイドでは特定のヘッダを、フロントエンドは新しいシンプルな API を使って取得できる。
Chrome 84 以降では chrome://flags/#enable-experimental-web-platform-features
を有効にすることで利用できる。
User-Agent Client Hints にデフォルトで含まれるもの
Sec-CH-UA
... ブラウザ名と major/significant バージョンSec-CH-UA-Mobile
... モバイルデバイスかどうか (bool)
仕様の変更は今現在進んでいるので、デフォルトセットに変更があるかも。
これまでの UA の取得方法
navigator.userAgent
navigator.platform
(非推奨)navigator.appVersion
(非推奨)User-Agent
HTTP ヘッダ
User-Agent Client Hints への移行
前提として Secure Context である必要があるので注意。
フロントエンド
navigator.userAgentData
を使う
if (navigator.userAgentData) { // use hints } else { // fall back to user-agent string parse }
navigator.userAgentData
はブラウザのブランド名とバージョンをプロパティとして持っている。
> navigator.userAgentData < NavigatorUAData {brands: Array(3), mobile: false} brands: Array(3) 0: {brand: " Not;A Brand", version: "99"} 1: {brand: "Google Chrome", version: "91"} 2: {brand: "Chromium", version: "91"} length: 3 __proto__: Array(0) mobile: false __proto__: NavigatorUAData
より詳細な情報がほしい場合は navigator.userAgentData.getHighEntroyValues
を使う。Promise で返ってくることに注意。
> navigator.userAgentData .getHighEntropyValues(["architecture", "bitness", "model", "platform", "platformVersion", "uaFullVersion"]) .then(ua => { console.log(ua) }); < Promise {<pending>} < VM770:3 {architecture: "x86", model: "", platform: "macOS", platformVersion: "10_15_7", uaFullVersion: "91.0.4472.77"}
- モバイルの判定には
navigrator.userAgentData.mobile
を使う
const isMobile = navigator.userAgentData.mobile;
サーバーサイド
User-Agent
の代わりに Sec-CH-*
ヘッダを見るようにする。Chrome 91.0.4472.77 では、次のような HTTP リクエストヘッダがついている。
sec-ch-ua: " Not;A Brand";v="99", "Google Chrome";v="91", "Chromium";v="91" sec-ch-ua-mobile: ?0
さらに情報がほしい場合は Accept-CH
で指定すると、後続のリクエストから取得できる。
Accept-CH: Sec-CH-UA-Mobile, Sec-CH-UA-Model, Sec-CH-UA-Platform, Sec-CH-UA
もし First リクエストから取得したい場合は Critical-CH
ヘッダを使うらしい(試していないので未確認)。Critical-CH
ヘッダを使うと、ブラウザはそのヘッダを付けてリクエストをやり直す。
Critical-CH
は Accept-CH
と同じ値を持たなければいけない。
Critical-CH: Sec-CH-UA-Mobile, Sec-CH-UA-Model, Sec-CH-UA-Platform, Sec-CH-UA
Cross Origin リクエストの場合
https://blog.site で https://cdn.site のリソースを読み込んでいる場合、https://blog.site は Sec-CH-UA-Platform
をリクエストして取得できるが、https://cdn.site は取得できない。そのため、Permissions-Policy で明示的に https://cdn.site に委任する必要がある。委任できるリストは https://wicg.github.io/client-hints-infrastructure/#policy-controlled-client-hints-features で確認できる。
iframe の場合
blog.site
に次のような iframe を埋め込むと、そのさきの https://widget.site
は UH-UA-Model
を取得できる。
<iframe src="https://widget.site" allow="ch-ua-model"></iframe>