[javascript] HTML 태그를 HTML 엔티티로 이스케이프하는 가장 빠른 방법은 무엇입니까?
나는 일을 포함하는 크롬 확장 프로그램 쓰고 있어요 많은 문자열 살균 : 다음 작업을 할 수 변환하여, HTML 태그를 포함 <
, >
과 &
에 <
, >
그리고 &
각각을,.
(즉, PHP와 동일 htmlspecialchars(str, ENT_NOQUOTES)
합니다. 큰 따옴표 문자를 변환 할 필요가 없다고 생각합니다.)
이것은 내가 지금까지 찾은 가장 빠른 기능입니다.
function safe_tags(str) {
return str.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>') ;
}
그러나 한 번에 수천 개의 문자열을 실행해야 할 때 여전히 큰 지연이 있습니다.
누구든지 이것을 개선 할 수 있습니까? 차이가 나는 경우 대부분 10 ~ 150 자 사이의 문자열에 사용됩니다.
(내가 가지고 있던 한 가지 아이디어는보다 큼 기호를 인코딩하는 것을 귀찮게하지 않는 것이 었습니다. 이로 인해 실제 위험이 있습니까?)
답변
콜백 함수를 전달하여 교체를 수행 할 수 있습니다.
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
함수를 반복적 으로 호출하고 Dmitrij가 제안한 DOM 메서드를 사용하는 것과 비교 합니다.
당신의 길은 더 빠른 것 같습니다 …
그래도 왜 필요합니까?
답변
이를 수행 할 수있는 한 가지 방법은 다음과 같습니다.
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>"
답변
더 빠르고 / 짧은 솔루션은 다음과 같습니다.
escaped = new Option(html).innerHTML
이것은 Option 요소가 이러한 종류의 자동 이스케이프를 수행하는 생성자를 유지하는 JavaScript의 이상한 흔적과 관련이 있습니다.
답변
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, '>');
}
답변
가장 빠른 방법은 다음과 같습니다.
function escapeHTML(html) {
return document.createElement('div').appendChild(document.createTextNode(html)).parentNode.innerHTML;
}
이 방법은 ‘replace’를 기반으로하는 방법보다 약 두 배 빠릅니다 . http://jsperf.com/htmlencoderegex/35를 참조하십시오 .
답변
올인원 스크립트 :
// 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;
}