jQuery를 사용하여 HTML 문자열 이스케이프 처리
-
09-06-2019 - |
문제
문자열에서 HTML을 이스케이프하는 쉬운 방법을 아는 사람이 있습니까? jQuery?임의의 문자열을 전달하고 HTML 페이지에 표시하기 위해 적절하게 이스케이프 처리할 수 있어야 합니다(JavaScript/HTML 삽입 공격 방지).이 작업을 수행하기 위해 jQuery를 확장하는 것이 가능하다고 확신하지만 현재로서는 이를 수행할 수 있는 프레임워크에 대해 충분히 알지 못합니다.
해결책
사용하기 때문에 jQuery, 당신은 요소를 설정할 수 있습니다 text
특성:
// before:
// <div class="someClass">text</div>
var someHtmlString = "<script>alert('hi!');</script>";
// set a DIV's text:
$("div.someClass").text(someHtmlString);
// after:
// <div class="someClass"><script>alert('hi!');</script></div>
// get the text in a string:
var escaped = $("<div>").text(someHtmlString).html();
// value:
// <script>alert('hi!');</script>
다른 팁
도 있습니다 mustache.js의 솔루션
var entityMap = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": ''',
'/': '/',
'`': '`',
'=': '='
};
function escapeHtml (string) {
return String(string).replace(/[&<>"'`=\/]/g, function (s) {
return entityMap[s];
});
}
$('<div/>').text('This is fun & stuff').html(); // "This is fun & stuff"
원천: http://debuggable.com/posts/encode-ncode-entities-with-jquery:480f4dd6-13cc-4ce9-8071-4710cbddd56cb
당신이 HTML을 탈출하고 있다면, 내가 생각할 수있는 세 가지만 있습니다.
html.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
유스 케이스에 따라 다음과 같은 작업을 수행해야 할 수도 있습니다. "
에게 "
. 목록이 충분히 커지면 배열 만 사용합니다.
var escaped = html;
var findReplace = [[/&/g, "&"], [/</g, "<"], [/>/g, ">"], [/"/g, """]]
for(var item in findReplace)
escaped = escaped.replace(findReplace[item][0], findReplace[item][1]);
encodeURIComponent()
HTML이 아닌 URL에 대해서만 탈출합니다.
나는 이것을하는 작은 작은 기능을 썼다. 그것은 단지 탈출됩니다 "
, &
, <
그리고 >
(그러나 보통 그게 어쨌든 필요한 전부입니다). 이전에 제안 된 솔루션보다 약간 더 우아합니다. 하나 .replace()
모든 변환을 수행합니다. (편집 2 : 코드 복잡성 감소 기능을 더 작고 깔끔하게 만드는 원래 코드가 궁금하다면이 답변의 끝을 참조하십시오.)
function escapeHtml(text) {
'use strict';
return text.replace(/[\"&<>]/g, function (a) {
return { '"': '"', '&': '&', '<': '<', '>': '>' }[a];
});
}
이것은 평범한 JavaScript이며 jQuery가 사용되지 않았습니다.
탈출 /
그리고 '
~도
응답으로 편집 mklement댓글.
위의 기능은 모든 문자를 포함하도록 쉽게 확장 될 수 있습니다. 탈출 할 더 많은 문자를 지정하려면 정규 표현식에 문자 클래스에 두 문자를 삽입하십시오 (즉, 내부의 내부 /[...]/g
) 및 항목으로 chr
물체. (편집 2 : 같은 방식 으로이 기능도 단축되었습니다.)
function escapeHtml(text) {
'use strict';
return text.replace(/[\"&'\/<>]/g, function (a) {
return {
'"': '"', '&': '&', "'": ''',
'/': '/', '<': '<', '>': '>'
}[a];
});
}
위의 사용에 주목하십시오 '
아포스트로피 (상징적 실체 '
대신 사용되었을 수 있습니다 - XML에 정의되어 있지만 원래 HTML 사양에 포함되어 있지 않으므로 모든 브라우저에서 지원되지 않을 수 있습니다. 보다: HTML 문자 인코딩에 대한 Wikipedia 기사). 또한 10 진수 엔티티를 사용하는 것이 16 진수를 사용하는 것보다 더 널리 지원된다는 것을 읽는 것을 기억하지만 지금은 그 소스를 찾을 수는 없습니다. (그리고 16 진수를 지원하지 않는 많은 브라우저가있을 수 없습니다.)
메모: 첨가 /
그리고 '
탈출 된 캐릭터 목록에는 HTML에 특별한 의미가없고 필요 탈출.
원래의 escapeHtml
기능
편집 2 : 원래 함수는 변수를 사용했습니다 (chr
)에 필요한 개체를 저장합니다 .replace()
콜백. 이 변수는 또한 범위를 범위로 만들기 위해 추가 익명 기능이 필요하여 기능을 조금 더 크고 복잡하게 만듭니다.
var escapeHtml = (function () {
'use strict';
var chr = { '"': '"', '&': '&', '<': '<', '>': '>' };
return function (text) {
return text.replace(/[\"&<>]/g, function (a) { return chr[a]; });
};
}());
두 버전 중 어느 것이 더 빠른지 테스트하지 않았습니다. 그렇다면 여기에 정보와 링크를 추가하십시오.
나는 이 파티에 얼마나 늦었는지 알고 있지만 jQuery가 필요하지 않은 매우 쉬운 솔루션을 가지고 있습니다.
escaped = new Option(unescaped).innerHTML;
편집하다:이것은 따옴표를 벗어나지 않습니다.따옴표를 이스케이프해야 하는 유일한 경우는 콘텐츠를 HTML 문자열 내의 속성에 인라인으로 붙여넣는 경우입니다.이렇게 하는 것이 좋은 디자인이 될 경우는 상상하기 어렵습니다.
편집 2:성능이 중요한 경우 최고 성능 솔루션(약 50% 정도)은 여전히 일련의 정규식 대체입니다.최신 브라우저는 정규 표현식에 연산자가 없고 문자열만 포함되어 있음을 감지하여 모든 표현식을 단일 작업으로 축소합니다.
다음은 깨끗하고 명확한 JavaScript 기능입니다. "몇 <많은"과 같은 텍스트를 "몇 <많은"으로 탈출합니다.
function escapeHtmlEntities (str) {
if (typeof jQuery !== 'undefined') {
// Create an empty div to use as a container,
// then put the raw text in and get the HTML
// equivalent out.
return jQuery('<div/>').text(str).html();
}
// No jQuery, so use string replace.
return str
.replace(/&/g, '&')
.replace(/>/g, '>')
.replace(/</g, '<')
.replace(/"/g, '"')
.replace(/'/g, ''');
}
마지막 테스트 후 나는 추천 할 수 있습니다 가장 빠른 그리고 완전히 크로스 브라우저 호환 가능 기본 JavaScript (dom) 솔루션 :
function HTMLescape(html){
return document.createElement('div')
.appendChild(document.createTextNode(html))
.parentNode
.innerHTML
}
여러 번 반복하면 한 번 준비된 변수로 수행 할 수 있습니다.
//prepare variables
var DOMtext = document.createTextNode("test");
var DOMnative = document.createElement("span");
DOMnative.appendChild(DOMtext);
//main work for each case
function HTMLescape(html){
DOMtext.nodeValue = html;
return DOMnative.innerHTML
}
노력하다 밑줄 lib, 그것은 jQuery와 함께 작동합니다.
_.str.escapeHTML('<div>Blah blah blah</div>')
산출:
'<div>Blah blah blah</div>'
chustache.js 예제를 추가했습니다 escapeHTML()
문자열 객체에 대한 메소드.
var __entityMap = {
"&": "&",
"<": "<",
">": ">",
'"': '"',
"'": ''',
"/": '/'
};
String.prototype.escapeHTML = function() {
return String(this).replace(/[&<>"'\/]/g, function (s) {
return __entityMap[s];
});
}
그렇게하면 사용하기가 매우 쉽습니다 "Some <text>, more Text&Text".escapeHTML()
escape()
그리고 unescape()
HTML이 아닌 URL의 문자열을 인코딩 / 디코딩하기위한 것입니다.
실제로, 나는 다음 스 니펫을 사용하여 프레임 워크가 필요하지 않은 트릭을 수행합니다.
var escapedHtml = html.replace(/&/g, '&')
.replace(/>/g, '>')
.replace(/</g, '<')
.replace(/"/g, '"')
.replace(/'/g, ''');
aldscore.js가있는 경우 사용하십시오 _.escape
(위에 게시 된 jQuery 방법보다 효율적) : :
_.escape('Curly, Larry & Moe'); // returns: Curly, Larry & Moe
REGEX 경로를 사용하는 경우 위의 TGHW 예에 오류가 발생합니다.
<!-- WON'T WORK - item[0] is an index, not an item -->
var escaped = html;
var findReplace = [[/&/g, "&"], [/</g, "<"], [/>/g,">"], [/"/g,
"""]]
for(var item in findReplace) {
escaped = escaped.replace(item[0], item[1]);
}
<!-- WORKS - findReplace[item[]] correctly references contents -->
var escaped = html;
var findReplace = [[/&/g, "&"], [/</g, "<"], [/>/g, ">"], [/"/g, """]]
for(var item in findReplace) {
escaped = escaped.replace(findReplace[item[0]], findReplace[item[1]]);
}
이것은 좋은 안전한 예입니다 ...
function escapeHtml(str) {
if (typeof(str) == "string"){
try{
var newStr = "";
var nextCode = 0;
for (var i = 0;i < str.length;i++){
nextCode = str.charCodeAt(i);
if (nextCode > 0 && nextCode < 128){
newStr += "&#"+nextCode+";";
}
else{
newStr += "?";
}
}
return newStr;
}
catch(err){
}
}
else{
return str;
}
}
바닐라 JS로 쉽게 할 수 있습니다.
텍스트 노드를 추가하기 만하면 문서를 추가하십시오. 브라우저에 의해 탈출됩니다.
var escaped = document.createTextNode("<HTML TO/ESCAPE/>")
document.getElementById("[PARENT_NODE]").appendChild(escaped)
(function(undefined){
var charsToReplace = {
'&': '&',
'<': '<',
'>': '>'
};
var replaceReg = new RegExp("[" + Object.keys(charsToReplace).join("") + "]", "g");
var replaceFn = function(tag){ return charsToReplace[tag] || tag; };
var replaceRegF = function(replaceMap) {
return (new RegExp("[" + Object.keys(charsToReplace).concat(Object.keys(replaceMap)).join("") + "]", "gi"));
};
var replaceFnF = function(replaceMap) {
return function(tag){ return replaceMap[tag] || charsToReplace[tag] || tag; };
};
String.prototype.htmlEscape = function(replaceMap) {
if (replaceMap === undefined) return this.replace(replaceReg, replaceFn);
return this.replace(replaceRegF(replaceMap), replaceFnF(replaceMap));
};
})();
글로벌 변수가없고 일부 메모리 최적화. 용법:
"some<tag>and&symbol©".htmlEscape({'©': '©'})
결과는 다음과 같습니다.
"some<tag>and&symbol©"
function htmlEscape(str) {
var stringval="";
$.each(str, function (i, element) {
alert(element);
stringval += element
.replace(/&/g, '&')
.replace(/"/g, '"')
.replace(/'/g, ''')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(' ', '-')
.replace('?', '-')
.replace(':', '-')
.replace('|', '-')
.replace('.', '-');
});
alert(stringval);
return String(stringval);
}
jQuery가 필요없는 2 가지 간단한 방법 ...
당신은 할 수 있습니다 모든 문자를 인코딩합니다 다음과 같은 문자열에서 :
function encode(e){return e.replace(/[^]/g,function(e){return"&#"+e.charCodeAt(0)+";"})}
아니면 그냥 주인공을 대상으로합니다 에 대해서 걱정하다 &
, 라인 브레이크, <
, >
, "
그리고 '
처럼:
function encode(r){
return r.replace(/[\x26\x0A\<>'"]/g,function(r){return"&#"+r.charCodeAt(0)+";"})
}
var myString='Encode HTML entities!\n"Safe" escape <script></'+'script> & other tags!';
test.value=encode(myString);
testing.innerHTML=encode(myString);
/*************
* \x26 is &ersand (it has to be first),
* \x0A is newline,
*************/
<p><b>What JavaScript Generated:</b></p>
<textarea id=test rows="3" cols="55"></textarea>
<p><b>What It Renders Too In HTML:</b></p>
<div id="testing">www.WHAK.com</div>
일반 JavaScript Escaping 예 :
function escapeHtml(text) {
var div = document.createElement('div');
div.innerText = text;
return div.innerHTML;
}
escapeHtml("<script>alert('hi!');</script>")
// "<script>alert('hi!');</script>"
function htmlDecode(t){
if (t) return $('<div />').html(t).text();
}
매력처럼 작동합니다
이 답변 jQuery 및 일반 JS 방법을 제공하지만 DOM을 사용하지 않고 가장 짧습니다.
unescape(escape("It's > 20% less complicated this way."))
탈출 된 문자열 : It%27s%20%3E%2020%25%20less%20complicated%20this%20way.
탈출 한 공간이 당신을 괴롭 히면 시도하십시오.
unescape(escape("It's > 20% less complicated this way.").replace(/%20/g, " "))
탈출 된 문자열 : It%27s %3E 20%25 less complicated this way.
불행히도, escape()
기능은 JavaScript 버전 1.5에서 더 이상 사용되지 않습니다. encodeURI()
또는 encodeURIComponent()
대안이지만 무시합니다 '
, 마지막 코드 줄은 다음과 같습니다.
decodeURI(encodeURI("It's > 20% less complicated this way.").replace(/%20/g, " ").replace("'", '%27'))
모든 주요 브라우저는 여전히 짧은 코드를 지원하며 이전 웹 사이트의 수를 감안할 때 곧 변경 될 것입니다.
이 정보를 a에 저장하는 경우 데이터 베이스, a를 사용하여 HTML을 피하는 것은 잘못된 일입니다 고객 입장에서 스크립트, 이것은에서 수행해야합니다 섬기는 사람. 그렇지 않으면 XSS 보호를 우회하기가 쉽습니다.
내 요점을 명확하게하기 위해 여기에 답 중 하나를 사용하는 예는 다음과 같습니다.
블로그의 주석에서 HTML을 피한 다음 서버에 게시하는 기능 EscapeHtml 기능을 사용한다고 가정 해 봅시다.
var entityMap = {
"&": "&",
"<": "<",
">": ">",
'"': '"',
"'": ''',
"/": '/'
};
function escapeHtml(string) {
return String(string).replace(/[&<>"'\/]/g, function (s) {
return entityMap[s];
});
}
사용자는 다음과 같습니다.
- 게시물 요청 매개 변수를 편집하고 주석을 JavaScript 코드로 바꾸십시오.
- 브라우저 콘솔을 사용하여 EscapeHtml 기능을 덮어 씁니다.
사용자 가이 스 니펫을 콘솔에 붙여 넣으면 XSS 유효성 검사를 우회합니다.
function escapeHtml(string){
return string
}
재사용을 방지하지 않으면 모든 솔루션이 쓸모가 없습니다. 예를 들어 대부분의 솔루션은 계속 탈출합니다. &
에게 &
.
escapeHtml = function (s) {
return s ? s.replace(
/[&<>'"]/g,
function (c, offset, str) {
if (c === "&") {
var substr = str.substring(offset, offset + 6);
if (/&(amp|lt|gt|apos|quot);/.test(substr)) {
// already escaped, do not re-escape
return c;
}
}
return "&" + {
"&": "amp",
"<": "lt",
">": "gt",
"'": "apos",
'"': "quot"
}[c] + ";";
}
) : "";
};