🏦
【初心者向け】ブラウザのエンコーディングについて
こんにちは、ワニかず@40歳 出戻りエンジニアです。
FlutterとDjangoの開発の勉強をしていたのですが、
- ブラウザ側(HTML + JavaScript)では文字化けしない
- Flutterアプリ側では文字化けする
という現象が起きた中で、
ブラウザのエンコーディングについて調べたのでまとめました。
盛大に文字化けしています。
構成
原因
- レスポンスに明示的に
content_type='charset=utf-8'
を指定しなかったが - ブラウザ側が、独自のエンコーディング検出アルゴリズムを持っている
- そのため、ブラウザ側では文字化けしなかった
ということでした。
※Djangoのデフォルト文字コードはutf-8のようですが、プロジェクト内で上手く機能していない。
これに関しては別途時間があるときに調べたい。
ブラウザの文字コード判定処理
Content-Type charset が指定されていない場合、以下の順序で文字コードを判定します。
- BOMチェック(優先順位: 最高)
- ファイルの先頭バイトをチェックし、BOM (Byte Order Mark) の有無を確認
- BOMが見つかった場合、それに応じた文字コードを使用
- EF BB BF → UTF-8
- FE FF → UTF-16BE
- FF FE → UTF-16LE
- HTMLのメタタグチェック(優先順位: 2番目)
<meta charset="UTF-8">
// または古い形式
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- ヒューリスティック解析(優先順位: 最低)
- バイトパターン分析を行い、文字コードを推測
- 例えば:
- 特定のバイトシーケンスがUTF-8として有効かチェック
- 各文字コードでデコードを試み、エラー率が最も低いものを選択
- 言語固有の文字の出現頻度を分析
主要なブラウザ(Chrome、Firefox、Safari)は、それぞれ独自のエンコーディング検出アルゴリズムを持っています:
- Chrome: Compact Language Detector (CLD)
- Firefox: Universal Character Set Detector
- Safari: WebKit's character encoding detector
このため、Content-Type charset がなくても正常に日本語が表示される理由は:
- HTMLファイル内にmetaタグで文字コードが指定されている
- または、ブラウザの文字コード判定アルゴリズムが日本語のパターンを正しく認識している
ベストプラクティスとしては、以下が推奨されます:
- Content-Type charset を明示的に指定する
- HTMLファイルの先頭にmeta charset タグを配置する
- 可能であればBOMを付与する
これにより、ブラウザの推測に頼ることなく、確実に意図した文字コードで表示されます。
おしまいに
ブラウザの大半は優しさでできているようです。
Discussion