次のジョブのlotを実行するChrome拡張機能を作成しています。HTMLタグを含むmight文字列のサニタイズ、 <
、>
および&
をそれぞれ<
、>
および&
に変換します。
(言い換えると、PHPのhtmlspecialchars(str, ENT_NOQUOTES)
と同じです。二重引用符文字を変換する必要は本当にないと思います。)
これは私がこれまでに見つけた最速の機能です。
function safe_tags(str) {
return str.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>') ;
}
しかし、一度に数千の文字列を実行しなければならないとき、まだ大きな遅れがあります。
誰でもこれを改善できますか?違いがある場合は、主に10〜150文字の文字列用です。
(私が持っていたアイデアの1つは、大なり記号をエンコードすることではありませんでした。実際に危険がありますか?)
コールバック関数を渡して、置換を実行してみてください。
var tagsToReplace = {
'&': '&',
'<': '<',
'>': '>'
};
function replaceTag(tag) {
return tagsToReplace[tag] || tag;
}
function safe_tags_replace(str) {
return str.replace(/[&<>]/g, replaceTag);
}
ここにパフォーマンステストがあります: http://jsperf.com/encode-html-entitiesreplace
関数を繰り返し呼び出し、DOMを使用することと比較しますDmitrijによって提案された方法。
あなたの方法は速いようです...
なぜそれが必要なのですか?
これを行う1つの方法を次に示します。
var escape = document.createElement('textarea');
function escapeHTML(html) {
escape.textContent = html;
return escape.innerHTML;
}
function unescapeHTML(html) {
escape.innerHTML = html;
return escape.textContent;
}
プロトタイプ関数としてのMartijnの方法:
String.prototype.escape = function() {
var tagsToReplace = {
'&': '&',
'<': '<',
'>': '>'
};
return this.replace(/[&<>]/g, function(tag) {
return tagsToReplace[tag] || tag;
});
};
var a = "<abc>";
var b = a.escape(); // "<abc>"
最速の方法は次のとおりです。
function escapeHTML(html) {
return document.createElement('div').appendChild(document.createTextNode(html)).parentNode.innerHTML;
}
このメソッドは、「置換」に基づくメソッドよりも約2倍高速です。 http://jsperf.com/htmlencoderegex/35 を参照してください。
AngularJSソースコードには angular-sanitize.js の内部バージョンもあります。
var SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g,
// Match everything outside of normal chars and " (quote character)
NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/g;
/**
* Escapes all potentially dangerous characters, so that the
* resulting string can be safely inserted into attribute or
* element text.
* @param value
* @returns {string} escaped text
*/
function encodeEntities(value) {
return value.
replace(/&/g, '&').
replace(SURROGATE_PAIR_REGEXP, function(value) {
var hi = value.charCodeAt(0);
var low = value.charCodeAt(1);
return '&#' + (((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000) + ';';
}).
replace(NON_ALPHANUMERIC_REGEXP, function(value) {
return '&#' + value.charCodeAt(0) + ';';
}).
replace(/</g, '<').
replace(/>/g, '>');
}
オールインワンスクリプト:
// HTML entities Encode/Decode
function htmlspecialchars(str) {
var map = {
"&": "&",
"<": "<",
">": ">",
"\"": """,
"'": "'" // ' -> ' for XML only
};
return str.replace(/[&<>"']/g, function(m) { return map[m]; });
}
function htmlspecialchars_decode(str) {
var map = {
"&": "&",
"<": "<",
">": ">",
""": "\"",
"'": "'"
};
return str.replace(/(&|<|>|"|')/g, function(m) { return map[m]; });
}
function htmlentities(str) {
var textarea = document.createElement("textarea");
textarea.innerHTML = str;
return textarea.innerHTML;
}
function htmlentities_decode(str) {
var textarea = document.createElement("textarea");
textarea.innerHTML = str;
return textarea.value;
}
さらに迅速/短いソリューションは次のとおりです。
escaped = new Option(html).innerHTML
これは、Option要素がこの種のエスケープを自動的に行うコンストラクターを保持するJavaScriptの奇妙な痕跡に関連しています。
function encode(r) {
return r.replace(/[\x26\x0A\x3c\x3e\x22\x27]/g, function(r) {
return "&#" + r.charCodeAt(0) + ";";
});
}
test.value=encode('How to encode\nonly html tags &<>\'" Nice & fast!');
/*
\x26 is &ersand (it has to be first),
\x0A is newline,
\x22 is ",
\x27 is ',
\x3c is <,
\x3e is >
*/
<textarea id=test rows=11 cols=55>www.WHAK.com</textarea>
速度については完全にはわかりませんが、単純さを求めているなら、lodash/underscore escape 関数を使用することをお勧めします。
"マーク(javascript)を使用した単一関数としてのMartijnのメソッド:
function escapeHTML(html) {
var fn=function(tag) {
var charsToReplace = {
'&': '&',
'<': '<',
'>': '>',
'"': '"'
};
return charsToReplace[tag] || tag;
}
return html.replace(/[&<>"]/g, fn);
}