BraveブラウザでAmazonの中古品をカートに追加できない問題を探る
結論
Prevent sites from fingerprinting me based on my language preferences という設定を無効化することで、Accept-Language
ヘッダーの値の言語タグが language
(2文字)から language-region
(2文字プラス2文字) に変化し、Amazonで買い物ができるようになりました。
まず再現方法について。
- MacBook本体の言語: 1. English 2. Japanese
- Brave本体の言語: 1. Japanese 2. English
この状態で「カートに追加する」を押すと、XHRHttpRequestによるPostリクエストが406エラーになる。
SPAのAPIリクエストに対して406を返す必要は全く感じないが(だってユーザーは見ない)、とりあえずそういう仕様のようだ。
エラーメッセージは次の通り。
{"message":"The requested language/locale supplied in the request Accept-Language header is not currently supported.","url":"https://api.amazon.com/shop"}
原因となったリクエストヘッダーは Accept-Language: ja;q=0.8
言語設定で日本語と英語を選択しているのに、Accept-Language
で ja
だけを使用していることに疑問を感じる。他のブラウザではどうだろう?また、他のリクエストではどうだろうか?
言語設定を 1. Japanese 2. English としたChromeからのリクエストは成功する。
興味深いことに、Preflight Request時点では私のBrave/Chromeのいずれも複数の言語でAccept-Languageを送信しているようだ。まとめるとこうなる。
Brave | Chrome | |
---|---|---|
Preflight Request | Accept-Language: ja,en;q=0.9 | Accept-Language: ja,en;q=0.9,ja-US;q=0.8 |
Post Request | Accept-Language: ja;q=0.8 | Accept-Language: en-US |
Post Response Code | 406 | 200 |
その他のリクエストではどうか?ということで、Google MapでのXHRHttpRequestについて調べてみた。
対象となるURLは https://www.google.co.jp/log
Brave | Chrome | |
---|---|---|
Preflight Request | accept-language: ja,en;q=0.9 | accept-language: ja,en;q=0.9,ja-US;q=0.8 |
Post Request | accept-language: ja;q=0.6 | accept-language: ja,en;q=0.9,ja-US;q=0.8 |
AmazonとGoogle Mapの例から言えることを考える。
- どちらもPreflight Requestでは手持ちのLanugageをすべて提示している
- BraveはPostリクエストで第一言語しか送らないかもしれない
- ChromeはPostリクエストで受け入れる言語をいい感じに変えている
新たな疑問と、それに対する仮説。
- ブラウザがリクエスト先に応じて
Accept-Language
ヘッダーを変えられるのはなぜ?- 同じドメインに対してリクエストした際の
Content-Language
レスポンスヘッダーを記憶しているとか?- その場合でも、ChromeがAmazonの中古品のカート追加でjaがうまく行かないロケールだと見破れる理由にはならない。
- 同じドメインに対してリクエストした際の
- Braveが
Accept-Language
ヘッダーの値を絞るのはなぜ?- フィンガープリンティング対策?
Block Fingerprintingを無効化するとAmazonでもカートに商品を追加できることが分かった!
brave://settings/?search=fingerprinting にアクセスし、Disabledに変更すれば良い。
Postリクエスト時の Accept-Language
ヘッダーが ja;q=0.8
から ja-JP
に変化している。
フィンガープリンティング対策?
この仮説がおそらく正しかった。関連しそうなPR(C++で1000行以上変更があり、ちょっと詳細は見てない)
Fingerprinting対策を無効化すれば買い物ができることは分かったが、Braveを使うなら有効化したいところ。そこで、 brave://flags/#reduce-accept-language から Accept-Language
ヘッダーの値を絞るフラグだけを無効化してみた。
しかし、結果は失敗!行けると思ったのに!