[jQuery]たった1行でHTML文字列をサニタイズし改行コードはbrタグに置き換えする

Read More



HTMLエスケープ、HTMLサニタイジング…

もう少し丁寧にいうと、
「HTMLに使う特定の文字をエスケープする」とか
「HTML文字列をサニタイズする」とか。

色んな言い方があるけどどう言っても大抵通じる。


HTMLで表示する際、"<>"みたいな文字列はそのまま書いてしまうとタグとして扱われるので結果として意図したものと違うものが表示されて困る。
HTMLで悪さをする特定の文字列を無害化するためには"lt;gt;"のようにエスケープ処理を施してやる必要がある。
ま、これらを指す言葉。


jQueryを使っている環境ならば長い関数を用意したりわけのわからないプラグインを入れたりせずとも
1行で簡単にHTML文字列を無害化し、改行コードもbrタグに置き換えができる。


--
■jQueryを使って1行でHTML文字列のサニタイズをする方法
<script type="text/javascript" language="JavaScript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(function() {
  $('input[name="btn_demo"]').on('click', function() {
    // 適当にそれっぽい値を用意
    var str = '!"#$%&\'()<br />aaa\nbbb';

    // HTMLサニタイジング(HTML文字列を無害化し、改行コードをbrタグに置き換え)
    var esc_str = $('<dummy>').text(str).html().replace(/\r\n|\r|\n/g, '<br>');

    // HTMLサニタイズしたものをHTMLとして出力
    $('#esc_str_id').html(esc_str);
  });
});
</script>
<input type="button" name="btn_demo" value="button" />
<div id="esc_str_id"></div>

こんな感じ。

■出力された結果
!"#$%&'()<br />aaa
bbb


■コードの内容
!"#$%&amp;'()&lt;br /&gt;aaa<br />bbb


demoも用意してみた。

■jQueryを使ったHTMLサニタイジングのdemo
http://xirasaya.com/demo/17/



--
jQueryでHTML文字列をサニタイズするのためにざっくり何をしているか。
 1.DOM要素としてdummyタグを生成。
 2.text({指定文字列})でdummyタグにテキストとしてぶち込む。この時点で無害化した文字列がDOMにセットされる。
 3.html()でdummyタグに書き込まれた内部コードを取得する。これで無害化した文字列を確保。
 4.replace()でサニタイズされた文字列から改行コードを抜き出しbrタグに変換。
 5.特定要素にhtml()で出力。これでbrタグのみが効く。


仮に3をtext()で読み込むと表面上の文字列を取得するので無害化前のものになってしまう。
また1ではDOM要素としてdummyタグを使っているがこれは何でも(例えばinputタグでも)構わない。
実際に画面にかかわるところに設置するわけではないから。



なお上記の例ではわかりやすくするために変数に代入して出力するのに2行にわけて書いたが1行だとこうなる。
$('#esc_str_id').html($('<dummy>').text(str).html().replace(/\r\n|\r|\n/g, '<br>'));



--
注意点としては古いブラウザではうまく動かない可能性があるかもしれないこと。
またjQueryのVerによっても動かないかも(試していない)。
少なくともjQueryのVer.1.9.1では動く。
ブラウザはIE11、Edgeは41、Firefox Quantumは58、Chromeは64(2018/02/27時点)