web-dev-qa-db-ja.com

jQueryを使用してHTMLをエスケープする

JQueryを使用してHTMLをエスケープするためのハックを思いついたので、誰かが問題を見つけたのではないかと思っています。

_$('<i></i>').text(TEXT_TO_ESCAPE).html();
_

JQueryはテキストを設定するコンテナを必要とするため、_<i>_タグは単なるダミーです。

これを行う簡単な方法はおそらくありますか?表示用ではなく、変数に保存されたテキストが必要なことに注意してください(そうでない場合は、単にelem.text(TEXT_TO_ESCAPE);を呼び出すことができます)。

ありがとう!

37
Michael Mior

これはかなり標準的な方法で、私のバージョンでは<div>しかし:

return $('<div/>').text(t).html();

Mike Samuelが指摘しているように、これは技術的に100%安全ではありませんが、実際にはおそらくかなり安全です。

現在のPrototype.jsはこれを行います:

function escapeHTML() {
    return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
}

しかし、「divにテキストを入れてHTMLを抽出する」トリックを使用していました。

_.escapeアンダースコア で、次のようになります:

// List of HTML entities for escaping.
var htmlEscapes = {
  '&': '&amp;',
  '<': '&lt;',
  '>': '&gt;',
  '"': '&quot;',
  "'": '&#x27;',
  '/': '&#x2F;'
};

// Regex containing the keys listed immediately above.
var htmlEscaper = /[&<>"'\/]/g;

// Escape a string for HTML interpolation.
_.escape = function(string) {
  return ('' + string).replace(htmlEscaper, function(match) {
    return htmlEscapes[match];
  });
};

これは、Prototypeのアプローチとほとんど同じです。私が最近行ったJavaScriptのほとんどは、アンダースコアを利用できるので、_.escape 最近。

62
mu is too short

html()が完全にエスケープされる保証はないため、結果は連結後に安全ではなくなる可能性があります。

html()innerHTMLに基づいており、ブラウザは、多くの期待に違反することなく、$("<i></i>").text("1 <").html()が_"1 <"_になるようにinnerHTMLを実装できます。 $("<i></i>").text("b>").html()は_"b>"_です。

次に、これら2つの個別に安全な結果を連結すると、_"1 <b>"_を取得します。これは明らかに、2つのプレーンテキスト部分の連結のHTMLバージョンではありません。

そのため、この方法は第一原理からの推論により安全ではなく、innerHTMLの仕様は広く守られていません(HTML5では対応しています)。

希望どおりに動作するかどうかを確認する最善の方法は、このようなコーナーケースをテストすることです。

11
Mike Samuel

それはうまくいくはずです。基本的には、Prototype.jsライブラリがそれを行う方法、または少なくとも以前はそれを使用していた方法です。私は通常、「。replace()」への3つの呼び出しでそれを行いますが、それはほとんどの習慣です。

1
Pointy