HTML エンティティ解除のガイド:& を & に戻す
API がエスケープされた引用符を返す、メールがアポストロフィの実体参照だらけ、テンプレート変数が改行タグを表示する。解除自体はすぐ終わりますが、どの層で戻すべきかの判断が難しいところです。
実体参照はどこから来るのか
多いのは二重エスケープです。保存時と出力時にそれぞれ変換され、画面には < が出ます。メールや RSS もよくあります。HTML の扱いが保守的で、実体参照の形をそのまま残すことがあるためです。
API のデータをコピーしたときにも遭遇します。JSON の文字列に引用符の実体参照が残っていると読みにくく、引用符に戻して初めて、JSON なのか HTML なのかただの文字なのか判断できます。
- 二重エスケープによる < の切り分け
- メール、RSS、API のエスケープ文字列の読解
- コピーしたソースを読める形に戻す
解除は1層だけ
ツールは HTML として1回解析します。アンパサンドは &、小なりは <、単一引用符の実体参照は引用符、 は改行しない空白になります。元が二重の &lt; なら結果は < で、< にはなりません。
結果はテキストとして表示され、実行されません。戻した script タグが動かないので、そのままページに貼れると錯覚しがちです。しかし innerHTML に渡した瞬間、それは本物のタグになります。
- 1回で1層。二重なら2回必要
- は改行しない空白。コードに貼ると厄介
- テキスト表示のみでスクリプトは実行されない
境界:戻した後に再判断する
解除は無害化ではありません。実体参照が山かっこに戻れば、そのテキストは再び HTML の意味を持ちます。利用者由来の内容なら、ページに戻す前に出力文脈に応じて再エスケープしてください。そうしないと自分で穴を開けます。
JavaScript のユニコードエスケープ、URL のパーセントエンコード、JSON のエスケープは対象外で、それぞれ規則が違います。16進数の数値文字参照は戻せますが、基本多言語面の外の文字は古い環境で表示が崩れることがあります。
- 解除は無害化ではない。再利用前に再エスケープ
- ユニコード、パーセント、JSON のエスケープは対象外
- 数値文字参照は使えるが、古い環境では絵文字が崩れる
よくある質問
&lt; が半分しか戻らないのはなぜですか
二重にエスケープされているからです。1回目でアンパサンドが & になり、残りは普通の文字として残ります。2回目で山かっこになります。どこかで二重変換している証拠なので、工程を見直す価値があります。
戻した結果をそのままページに置けますか
置けません。戻した文字には山かっこが含まれ、構文上の意味を持ちます。出力位置に応じて再エスケープしてから挿入してください。そうしないと文字がタグになります。
は何に戻りますか
改行しない空白(U+00A0)です。見た目は普通の空白ですが、ブラウザに畳まれず、行末でも切れません。コードや設定ファイルに貼ると「同じに見えて等しくない」原因になります。
関連ツール:HTMLエンティティデコーダー