jQuery로 HTML 문자열 이스케이프


609

누구나 jQuery의 문자열에서 HTML을 이스케이프하는 쉬운 방법을 알고 있습니까? 임의의 문자열을 전달할 수 있어야하고 HTML 페이지에 표시하기 위해 올바르게 이스케이프해야합니다 (JavaScript / HTML 주입 공격 방지). 나는 이것을하기 위해 jQuery를 확장 할 수 있다고 확신하지만, 이것을 달성하기 위해 현재 프레임 워크에 대해 충분히 모른다.


또한를 규칙적 참조 : jsperf.com/...
크리스토프 후씨

답변:


445

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">&lt;script&gt;alert('hi!');&lt;/script&gt;</div>

// get the text in a string:
var escaped = $("<div>").text(someHtmlString).html();
// value: 
// &lt;script&gt;alert('hi!');&lt;/script&gt;

57
이스케이프 된 버전을 얻으려면 $ ( "div.someClass"). html ()에 액세스해야한다는 요점을 놓쳤습니다.
Morten Christiansen

16
문자열에 공백이 있고 \ n \ r \ t 문자가 있으면 브라우저가 안전하지 않습니다.
nivcaner

20
@travis 이것은 jQuery 웹 사이트에 문서화되어 있습니다 : "다른 브라우저에서 HTML 파서의 변형으로 인해, 반환 된 텍스트는 줄 바꿈 및 기타 공백이 다를 수 있습니다." api.jquery.com/text
geofflee

3
이미이 솔루션을 사용하는 경우 @mklement, 당신은 같은 그 일을 뭔가 문제가되지 않습니다 : $(element2).attr("some-attr", $(element1).html());이 예를 참조하십시오 jsbin.com/atibig/1/edit은
트래비스

16
이것은 나쁜 따옴표와 큰 따옴표를 이스케이프하지 않습니다! wonko.com/post/html-escaping
Lior

601

mustache.js의 솔루션 도 있습니다

var entityMap = {
  '&': '&amp;',
  '<': '&lt;',
  '>': '&gt;',
  '"': '&quot;',
  "'": '&#39;',
  '/': '&#x2F;',
  '`': '&#x60;',
  '=': '&#x3D;'
};

function escapeHtml (string) {
  return String(string).replace(/[&<>"'`=\/]/g, function (s) {
    return entityMap[s];
  });
}

7
흥미롭게도 십진 형식 '의 엔티티에 맵핑되는 반면 16 진 형식을 사용 합니다. /
mklement0

43
이것은 받아 들일만한 대답이어야합니다-간단하고 효율적이며 종속성이 필요하지 않으며 모호한 해킹없이 의도 된 것을 정확하게 수행합니다.
lorefnon

6
변환하는 방법에 대한 지침 무엇 \n에가 <br>?
amwinter

2
다음은 소스에 대한 업데이트 된 링크입니다. github.com/janl/mustache.js/blob/…
mjackson

8
@amwinter, 엔티티 맵에 "\ n": '<br>'를 추가하고 위의 스크립트를 확장하여 regexp를 / [& <> " '\ /] | [\ n] / g
walv

182
$('<div/>').text('This is fun & stuff').html(); // "This is fun &amp; stuff"

출처 : http://debuggable.com/posts/encode-html-entities-with-jquery:480f4dd6-13cc-4ce9-8071-4710cbdd56cb


11
위의 답변에서 언급 했듯이이 솔루션은 공백을 보존한다고 보장하지 않습니다.
geofflee

47
이것은 작은 따옴표 나 큰 따옴표를 이스케이프 처리하지 않습니다. 값을 HTML 속성에 넣을 계획이라면 문제가 될 수 있습니다.
Kip

6
@Kip : @travis는 jQuery의 attr()메소드 (1.8.3 이상)가 자체 인코딩을 수행하여 인코딩되지 않은 문자열을 직접 전달할 수 있음을 발견했습니다 . 예 :$('<div/>').attr('test-attr', '\'Tis "fun" & stuff')[0].outerHTML
mklement0

1
@tarekahf 이상하다. 어떤 버전의 jQuery를 사용하고 있습니까? 예제 코드를 그대로 복사하여 붙여 넣으면 작동합니까? 최신 jQuery (3.1.0)에서 제대로 작동합니다 . jsbin.com/fazimigayo/1/edit?html,js,console,output (그리고 이전 버전에서도 작동해야 함)
Henrik N

1
@tarekahf 는 DOM에 첨부되지 않은 $('<div/>')div요소를 만듭니다 . 따라서 기존 요소는 변경되지 않습니다. jQuery가 동일한 $()함수를 사용하여 요소 ( $('div')) 를 찾고 요소 를 작성하는 방법과 몇 가지 추가 기능을 사용하는 방법이 약간 혼란 스럽다.
Henrik N

61

HTML을 피하고 있다면 실제로 필요한 것은 세 가지뿐입니다.

html.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");

사용 사례에 따라, 당신은 또한 같은 일을해야 할 수도 있습니다 "&quot;. 목록이 충분히 커지면 배열을 사용합니다.

var escaped = html;
var findReplace = [[/&/g, "&amp;"], [/</g, "&lt;"], [/>/g, "&gt;"], [/"/g, "&quot;"]]
for(var item in findReplace)
    escaped = escaped.replace(findReplace[item][0], findReplace[item][1]);

encodeURIComponent() HTML이 아닌 URL에 대해서만 이스케이프합니다.


13
이 정규 표현식은 문제의 HTML이 이미 개체를 이스케이프 한 경우 이상한 결과를 생성합니다. 예를 들어, "Tom & amp; Jerry"를 이스케이프하면 "Tom & amp; Jerry"가 생성됩니다
Ryan

12
현지 var에서 신고 할 때 사용하십시오 item. 어쨌든 for … in배열을 반복 할 때 루프를 전혀 사용하지 마십시오 ! for대신 일반 루프를 사용하십시오 . 아, encodeURIComponent아니야 escapeURIComponent.
Marcel Korpel

3
태그 속성을 사용하는 경우 따옴표 및 / 또는 큰 따옴표를 이스케이프해야합니다. htmlspecialchars에 대한 PHP 문서에는 유용한 변환 목록이 포함되어 있습니다. php.net/htmlspecialchars
geofflee

4
웹 사이트 어딘가에 영어가 아닌 문자를 사용하려는 경우이 기능을 사용하지 마십시오. 분명히 'é'와 같은 악센트가있는 문자 때문에이 기능은 사용되지 않습니다 &eacute. 다음은 참조 용 html 엔티티 목록입니다. w3schools.com/tags/ref_entities.asp
LoganWolfer

11
@Ryan :이 솔루션이 이미 인코딩 된 문자열을 올바르게 처리하지 못한다는 점을 지적 할 가치가 있지만,이 페이지의 모든 솔루션에 동일하게 적용되는 것도 가치가 없습니다.
mklement0

37

밑줄을 쉽게 사용할 수 있습니다.

_.escape(string) 

Underscore 는 기본 js가 제공하지 않는 많은 기능을 제공하는 유틸리티 라이브러리입니다. 밑줄과 동일한 API이지만 더 성능이 좋도록 다시 작성된 lodash 도 있습니다.


36

나는 이것을하는 작은 기능을 썼습니다. 그것은 단지 탈출 ", &, <>(그러나 보통 그 모든 어쨌든 필요이다). 그것은 다음은 사용에 앞서 제안 된 솔루션을 약간 더 우아한 하나를 .replace() 모든 변환을 수행 할 수 있습니다. ( 편집 2 : 코드 복잡성이 감소하여 기능이 훨씬 작고 깔끔해졌습니다. 원래 코드에 대해 궁금한 경우이 답변의 끝 부분을 참조하십시오.)

function escapeHtml(text) {
    'use strict';
    return text.replace(/[\"&<>]/g, function (a) {
        return { '"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;' }[a];
    });
}

이것은 일반 자바 스크립트이며 jQuery는 사용하지 않습니다.

이스케이프 /'너무

mklement 의 의견 에 따라 편집하십시오 .

위의 기능은 문자를 포함하도록 쉽게 확장 할 수 있습니다. 이스케이프 할 문자를 더 지정하려면 문자 클래스의 정규 표현식 (예 :) /[...]/gchr객체 의 항목에 모두 삽입하면 됩니다. ( 편집 2 : 같은 방식으로이 기능도 단축되었습니다.)

function escapeHtml(text) {
    'use strict';
    return text.replace(/[\"&'\/<>]/g, function (a) {
        return {
            '"': '&quot;', '&': '&amp;', "'": '&#39;',
            '/': '&#47;',  '<': '&lt;',  '>': '&gt;'
        }[a];
    });
}

위의 &#39;아포스트로피 사용에 유의하십시오 (기호 엔티티 &apos;는 대신 사용되었을 수 있습니다. XML로 정의되었지만 원래 HTML 스펙에 포함되지 않았으므로 모든 브라우저에서 지원되지 않을 수 있습니다) : HTML 문자 인코딩에 대한 위키피디아 기사 ). 또한 16 진수를 사용하는 것보다 10 진수 엔터티를 사용하는 것이 더 광범위하게 지원된다는 내용을 읽었지만 지금은 그 소스를 찾을 수 없습니다. 16 진수 엔터티를 지원하지 않는 브라우저는 많을 수 없습니다.

주 : 추가 /'그들이 HTML에서 특별한 의미를 가지고 있지 않으며하지 않기 때문에 탈출 문자 목록에 모든 것을 유용하지 않습니다 필요 이스케이프 할 수 있습니다.

원래 escapeHtml기능

편집 2 : 원래 함수는 변수 ( chr)를 사용하여 .replace()콜백에 필요한 객체를 저장했습니다 . 이 변수에는 범위를 지정하기 위해 추가 익명 함수가 필요했기 때문에 함수가 조금 더 크고 복잡해졌습니다.

var escapeHtml = (function () {
    'use strict';
    var chr = { '"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;' };
    return function (text) {
        return text.replace(/[\"&<>]/g, function (a) { return chr[a]; });
    };
}());

두 버전 중 어느 것이 더 빠른지 테스트하지 않았습니다. 그렇다면 여기에 정보와 링크를 추가하십시오.


시간을 내 주셔서 감사합니다, @Zrajm. 탈출 할 필요가 없다는 좋은 지적; 어떤 생각이 왜 모두 mustache.js하고 underscore.js그것을? 후자의 말하기 : 그것은 단지 숫자 엔티티 (대표 인식 '/에 ') 대문자 진수 할 때 양식을 취소 탈출. 따라서, 텍스트에서 탈출 mustache.js호기심 사용하는 - 혼합 진수의를. 십진수 형식-에서 올바르게 이스케이프 처리되지 않습니다 underscore.js. 다른 인기있는 도서관이 어떻게 처리하는지 궁금합니다.
mklement0

1
그 라이브러리 변환해야 (아마) 형태입니다 때문에 소문자 육각 형태는 가장 지원 형태 로는 . (물론 에서 변환 할 때 두 형식이 모두 작동해야합니다 .) – 아포스트로피 '에는 XML에서 일종의 예약 된 기능이 있으므로 XML (HTML은 아님)에 명명 된 엔티티가 &apos;있습니다. 왜 또는 어떤 방식으로 "예약 된"지 모르겠습니다. - 슬래시는 URL의에서 특별하다,하지만하지 않습니다 실제로 (URL 인코딩 뭔가 완전히 다른처럼) HTML을 탈출에 포함을 보증합니다.
zrajm

다시 &apos;: 정확 : XHTML 에서만 안전하게 사용 ; 크라우드 소스의 입 에서 곧바로 -강조 광산 : "(...) 호환 HTML 프로세서에서 읽거나 , (...) '또는 사용자 지정 엔터티 참조 사용이 지원되지 않을 수 있습니다 (...)"-실제로 : 최신 브라우저는 HTML 에서도 지원합니다 . 16 진수로 다시 입력하십시오. (동일한 소스; 강조점) : "x는 XML 문서에서 소문자 여야합니다. […] 대문자는 일반적인 스타일 이지만 대문자 와 소문자를 혼합 할 수 있습니다 ." 누가 슬래시를 인코딩하기로 결정했는지 궁금해합니다. 아마도 URI와 HTML 인코딩 사이의 혼란일까요?
mklement0

2
최종 생각 : 인코딩 /이 필요하지 않은 '것처럼 보이지만 인코딩 된 문자열이 작은 따옴표로 묶인 속성 값으로 사용되는 경우를 안전하게 처리하는 데 여전히 인코딩 이 유용 합니다 .
mklement0

둘 다 느립니다. 두 자리 마진으로 가장 빠른 솔루션은 함수 대신 문자열을 전달하는 일련의 대체입니다.
Adam Leggett

34

나는이 파티에 얼마나 늦었는지 알고 있지만 jQuery가 필요없는 매우 쉬운 솔루션을 가지고 있습니다.

escaped = new Option(unescaped).innerHTML;

편집 : 따옴표를 이스케이프하지 않습니다. 따옴표를 이스케이프해야하는 유일한 경우는 내용을 HTML 문자열 내 속성에 인라인으로 붙여 넣는 경우입니다. 이 작업을 수행하는 것이 좋은 디자인 일 경우를 상상하기가 어렵습니다.

편집 3 : 가장 빠른 해결책은 Saram에서 위의 답변을 확인하십시오. 가장 짧습니다.


이것은 현재 Firefox 52에서 따옴표를 바꾸지 않습니다.
getsetbro

1
이스케이프 따옴표는 기능적으로 만 기능적으로 관련이 있습니다. 우리는 이스케이프 처리 <하고 있기 때문에 >생성 된 컨텐츠의 의도가 속성으로 들어 가지 않는 한 따옴표를 이스케이프 처리해도 이점이 없습니다.
Adam Leggett

31

다음은 깨끗하고 명확한 JavaScript 함수입니다. "몇몇 <많은"과 같은 텍스트는 "몇몇 & lt; 많은"로 빠져 나갑니다.

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, '&amp;')
    .replace(/>/g, '&gt;')
    .replace(/</g, '&lt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&apos;');
}

28

마지막 테스트 후 브라우저 와 호환되는 기본 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
}

내 최종 성능 비교를보십시오 ( stack question ).


2
두 개의 노드를 사용해야합니까? 방법에 대한 하나 :var p = document.createElement('p'); p.textContent = html; return p.innerHTML;
댄 Dascalescu

2
@DanDascalescu : MDN 에 따르면 이 textContent기능은 Chrome 1 이상, Firefox 2, IE9, Opera 9.64 및 Safari 3 (후자는 "아마도 이전에 주석이 달린")에서만 지원됩니다. 따라서 OP의 "완전한 크로스 브라우저 호환"주장을 깨뜨릴 수 있습니다.
zb226

p.innerText = html; return p.innerHTML
Bekim Bacaj

24

Underscore.string lib를 사용해보십시오 .jQuery와 작동합니다.

_.str.escapeHTML('<div>Blah blah blah</div>')

산출:

'&lt;div&gt;Blah blah blah&lt;/div&gt;'

20
기본 밑줄 라이브러리에 _.escape()유틸리티 기능이 있습니다.
codeape

15

escapeHTML()문자열 객체에 메소드를 추가하는 mustache.js 예제를 향상 시켰습니다 .

var __entityMap = {
    "&": "&amp;",
    "<": "&lt;",
    ">": "&gt;",
    '"': '&quot;',
    "'": '&#39;',
    "/": '&#x2F;'
};

String.prototype.escapeHTML = function() {
    return String(this).replace(/[&<>"'\/]/g, function (s) {
        return __entityMap[s];
    });
}

그렇게하면 사용하기가 쉽습니다. "Some <text>, more Text&Text".escapeHTML()


유용하지만 __entityMap기능 로컬 범위 로 옮겼 습니다. 그리고으로이 모든 포장if (typeof String.prototype.escapeHTML !== 'function'){...}
FlameStorm

15

escape()그리고 unescape(), URL에 대한 코드 / 디코드 문자열 아니며 HTML된다.

실제로 다음 스 니펫을 사용하여 프레임 워크가 필요없는 트릭을 수행합니다.

var escapedHtml = html.replace(/&/g, '&amp;')
                      .replace(/>/g, '&gt;')
                      .replace(/</g, '&lt;')
                      .replace(/"/g, '&quot;')
                      .replace(/'/g, '&apos;');

당신이가는 경우 "다음의 당신은 적어도 추가 할 필요가 '싸움에``와. 이것들은 실제로 html의 요소 내부의 문자열 태그 데이터에만 필요합니다. html 데이터 자체 (태그 외부)의 경우 처음 3 개만 필요합니다.
Marius

10

underscore.js가있는 경우 다음을 사용하십시오 _.escape(위에 게시 된 jQuery 메소드보다 더 효율적 임).

_.escape('Curly, Larry & Moe'); // returns: Curly, Larry &amp; Moe

5

정규식 경로를 사용하는 경우 위의 tghw 예제에 오류가 있습니다.

<!-- WON'T WORK -  item[0] is an index, not an item -->

var escaped = html; 
var findReplace = [[/&/g, "&amp;"], [/</g, "&lt;"], [/>/g,"&gt;"], [/"/g,
"&quot;"]]

for(var item in findReplace) {
     escaped = escaped.replace(item[0], item[1]);   
}


<!-- WORKS - findReplace[item[]] correctly references contents -->

var escaped = html;
var findReplace = [[/&/g, "&amp;"], [/</g, "&lt;"], [/>/g, "&gt;"], [/"/g, "&quot;"]]

for(var item in findReplace) {
     escaped = escaped.replace(findReplace[item[0]], findReplace[item[1]]);
}

2
나는 그것이 (findReplace의 var 항목) {escaped = escaped.replace (findReplace [item] [0], findReplace [item] [1])이어야한다고 생각합니다. }
Chris Stephens

5

이것은 좋은 안전한 예입니다 ...

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;
    }
}

4
어떤 유형의 예외를 억제하고 있습니까?
Stefan Majewsky

3

바닐라 js로 쉽게 할 수 있습니다.

문서에 텍스트 노드를 추가하기 만하면됩니다. 브라우저에서 이스케이프됩니다.

var escaped = document.createTextNode("<HTML TO/ESCAPE/>")
document.getElementById("[PARENT_NODE]").appendChild(escaped)

2
(function(undefined){
    var charsToReplace = {
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;'
    };

    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({'©': '&copy;'})

결과는 다음과 같습니다

"some&lt;tag&gt;and&amp;symbol&copy;"

2

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 &ampersand (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>


2

일반 JavaScript 이스케이프 예제 :

function escapeHtml(text) {
    var div = document.createElement('div');
    div.innerText = text;
    return div.innerHTML;
}

escapeHtml("<script>alert('hi!');</script>")
// "&lt;script&gt;alert('hi!');&lt;/script&gt;"

3
코드 전용 답변은 문제 해결 방법을 설명하지 않기 때문에 권장하지 않습니다. 이 질문에 이미 수용된 다른 답변에서 개선 된 점 을 설명하려면 답변을 업데이트하십시오 . 또한이 질문은 9 살입니다. 최근 답변하지 않은 질문이있는 사용자에게 진심으로 감사드립니다. 좋은 답변을 작성하려면 어떻게합니까?를 검토하십시오 .
FluffyKitten

1
@FluffyKitten 여기에 당신이 알고 싶은 모든 것을 자세하게 설명하는 그러한 기능의 장단점에 대해 극도로 작성된 블로그 게시물이 있습니다. :) shebang.brandonmintern.com/…
db306

@ db306 코드 전용 답변이 스택 오버플로 지침을 충족하지 않기 때문에 답변이 저품질로 표시되었습니다 ( 좋은 답변 작성 방법 참조) . 검토 과정에서 내 의견이 추가되어 코드를 개선하는 데 필요한 사항, 즉 코드의 기능과 기존 답변의 개선 방법을 설명하기 위해 답변을 업데이트해야합니다. 공증인은 다른 검토 자로부터이를 승인합니다. 주석에 외부 링크를 추가해도 여전히 SO 지침을 충족하지 않습니다. 대신 Andrew는 관련 정보를 답변에 직접 포함시켜야합니다.
FluffyKitten

brandonmintern DOT com이 만료되어 주차되었습니다. 새 shebang 주소는 shebang.mintern.net/foolproof-html-escaping-in-javascript/입니다.
Brandon

0
function htmlEscape(str) {
    var stringval="";
    $.each(str, function (i, element) {
        alert(element);
        stringval += element
            .replace(/&/g, '&amp;')
            .replace(/"/g, '&quot;')
            .replace(/'/g, '&#39;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(' ', '-')
            .replace('?', '-')
            .replace(':', '-')
            .replace('|', '-')
            .replace('.', '-');
    });
    alert(stringval);
    return String(stringval);
}

0
function htmlDecode(t){
   if (t) return $('<div />').html(t).text();
}

매력처럼 작동합니다


text는 html 태그를 제거하지만 $ ( '<div />'). html (t) .html (); 작품
Bass Jobsen

0

이 답변 은 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'))

모든 주요 브라우저는 여전히 짧은 코드를 지원하며 오래된 웹 사이트의 수를 감안할 때 곧 바뀔 것이라고 의심합니다.


URL 인코딩 용입니다. 문제는 HTML 이스케이프에 관한 것인데 이는 매우 다릅니다.
thelem

@thelem, 문자열이 HTML에 포함 된 JavaScript 배열에 포함되어 있지는 않지만 일반 HTML 이스케이프에 관한 것이므로 동의하면 즉시 텍스트로 표시 할 수 있습니다.
Cees Timmerman

0

mustache.js솔루션을 위한 ES6 하나의 라이너

const escapeHTML = str => (str+'').replace(/[&<>"'`=\/]/g, s => ({'&': '&amp;','<': '&lt;','>': '&gt;','"': '&quot;',"'": '&#39;','/': '&#x2F;','`': '&#x60;','=': '&#x3D;'})[s]);

-2

이 정보를 데이터베이스 에 저장 하는 경우 클라이언트 측 스크립트를 사용하여 HTML을 이스케이프하는 것은 서버 에서 수행해야 합니다 . 그렇지 않으면 XSS 보호를 우회하기 쉽습니다.

내 요점을 명확히하기 위해 다음 답변 중 하나를 사용하는 예가 있습니다.

escapeHtml 함수를 사용하여 블로그의 주석에서 HTML을 이스케이프 처리 한 다음 서버에 게시한다고 가정하겠습니다.

var entityMap = {
    "&": "&amp;",
    "<": "&lt;",
    ">": "&gt;",
    '"': '&quot;',
    "'": '&#39;',
    "/": '&#x2F;'
  };

  function escapeHtml(string) {
    return String(string).replace(/[&<>"'\/]/g, function (s) {
      return entityMap[s];
    });
  }

사용자는 다음을 수행 할 수 있습니다.

  • POST 요청 매개 변수를 편집하고 주석을 Javascript 코드로 바꾸십시오.
  • 브라우저 콘솔을 사용하여 escapeHtml 함수를 덮어 씁니다.

사용자가이 스 니펫을 콘솔에 붙여 넣으면 XSS 유효성 검사를 무시합니다.

function escapeHtml(string){
   return string
}

동의하지 않습니다. 이 XSS 보호를 우회하려면 실제로 차단하고있는 XSS 공격 (이스케이프를 비활성화하는 스크립트 삽입)을 사용해야합니다. 어떤 경우에는 데이터가 표준 JSON을 반환해야하는 REST API에서 온 경우와 같이 실제로 클라이언트에서 이스케이프하는 것이 더 적합합니다.
ItalyPaleAle

@Qualcuno 클라이언트에서이 유효성 검사를 수행하고이 정보를 서버에 게시하여 유효성을 검증 한 경우 사용자는 간단히 요청을 편집 할 수 있으며 스크립트는 데이터베이스에 저장됩니다.
Kauê Gimenes

@Qualcuno 나는 요점을 더 명확하게하기 위해 몇 가지 예를 포함시켰다.
Kauê Gimenes

1
문제는 서버에서 수신 한 문자열을 이스케이프 하여 브라우저에 표시 하는 것입니다. 당신이 말하는 것은 (당신이있어 비록 오른쪽, 그리고 예전의 규칙에 간다 다른 일이 서버에이를 제출하기 전에 문자열을 탈출 관한 맹목적으로 클라이언트로부터 어떤 입력을 허용하지 )
ItalyPaleAle

@Qualcuno 이것은 Stackoverflow에서 인기있는 질문이며, 이것이 다루어야 할 중요한 포인트라고 생각합니다. 그게 내가 대답 한 이유입니다.
Kauê Gimenes

-2

다시 탈출을 막지 않으면 모든 솔루션이 쓸모가 없습니다. 예를 들어 대부분의 솔루션은 계속해서 이스케이프 &됩니다 &amp;.

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] + ";";
        }
    ) : "";
};

4
이를 이중 이스케이프라고하며 입력 데이터가 이미 이스케이프되지 않도록 수정해야합니다. 문자 그대로 & lt; 사용자에게? 아니면 텍스트가 다른 곳에서 재사용되고 탈출이 일어난 것에 달려 있습니까?
thelem
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.