자바 스크립트에서 HTML 특수 문자를 이스케이프 처리 할 수 ​​있습니까?


202

자바 스크립트 함수로 텍스트를 HTML로 표시하고 싶습니다. JS에서 HTML 특수 문자를 어떻게 피할 수 있습니까? API가 있습니까?


11
이 질문은 jQuery에 대해 묻지 않기 때문에 이것은 중복되지 않습니다. 나는 jQuery를 사용하지 않기 때문에 이것에만 관심이있다.
lvella

답변:


331
function escapeHtml(unsafe) {
    return unsafe
         .replace(/&/g, "&")
         .replace(/</g, "&lt;")
         .replace(/>/g, "&gt;")
         .replace(/"/g, "&quot;")
         .replace(/'/g, "&#039;");
 }

11
왜 "& # 039;" "&"; 아님 ?
sereda


2
replace()전화 통화 에서 정규 표현식 이 필요하지 않다고 생각 합니다. 평범한 단일 문자 문자열도 마찬가지입니다.
jamix

22
@jamix 최신 문자열은 간단한 정규 표현식을 최적화하는 반면 원시 문자열로 전역 대체를 수행 할 수는 없습니다.
bjornd

5
표준 API가 있습니까 아니면 이것이 유일한 방법입니까?
Sunil Garg

57

function escapeHtml(html){
  var text = document.createTextNode(html);
  var p = document.createElement('p');
  p.appendChild(text);
  return p.innerHTML;
}

// Escape while typing & print result
document.querySelector('input').addEventListener('input', e => {
  console.clear();
  console.log( escapeHtml(e.target.value) );
});
<input style='width:90%; padding:6px;' placeholder='&lt;b&gt;cool&lt;/b&gt;'>


여기서 일하지만 브라우저에서 오프라인으로 작동하지 않습니다

47

jQuery의 .text()함수를 사용할 수 있습니다 .

예를 들면 다음과 같습니다.

http://jsfiddle.net/9H6Ch/

.text()함수 에 관한 jQuery 문서에서 :

이 메소드는 HTML에서 올바르게 렌더링되도록 필요에 따라 제공된 문자열을 이스케이프해야합니다. 이를 위해 DOM 메소드 .createTextNode ()를 호출하고 문자열을 HTML로 해석하지 않습니다.

이전 버전의 jQuery 문서는 다음과 같이 표현했습니다 ( 중점 추가 ).

이 메소드는 HTML에서 올바르게 렌더링되도록 필요에 따라 제공된 문자열을 이스케이프해야합니다. 이를 위해 DOM 메소드 .createTextNode ()를 호출하여 특수 문자를 해당 HTML 엔티티 (예 : & lt; for <)로 바꿉니다 .


3
다음과 같이 변환하고 싶다면 신선한 요소에 사용할 수도 있습니다. const str = "foo<>'\"&"; $('<div>').text(str).html()yieldsfoo&lt;&gt;'"&amp;
amoebe

28

적절한 방법을 찾았다 고 생각합니다 ...

// Create a DOM Text node:
var text_node = document.createTextNode(unescaped_text);

// Get the HTML element where you want to insert the text into:
var elem = document.getElementById('msg_span');

// Optional: clear its old contents
//elem.innerHTML = '';

// Append the text node into it:
elem.appendChild(text_node);

나는 오늘 HTML에 대해 새로운 것을 배웠다. w3schools.com/jsref/met_document_createtextnode.asp .
Sellorio

1
다음과 같이 액세스하려고하면 텍스트 노드의 내용이 이스케이프되지 않습니다.document.createTextNode("<script>alert('Attack!')</script>").textContent
maechler

텍스트를 설정하는 것이 올바른 방법입니다. 그것은 또한 textContent이지만 분명히 잘 지원되지 않습니다. 그러나 일부 텍스트가 html 인 문자열을 작성하는 경우 여전히 작동하지 않지만 여전히 탈출해야합니다.
jgmjgm


21

이것은 지금까지 내가 본 가장 빠른 방법입니다. 또한 페이지의 요소를 추가, 제거 또는 변경하지 않고 모든 작업을 수행합니다.

function escapeHTML(unsafeText) {
    let div = document.createElement('div');
    div.innerText = unsafeText;
    return div.innerHTML;
}

7
경고 : 따옴표를 이스케이프 하지 않으므로 HTML 코드의 속성 값 내부에서 출력을 사용할 수 없습니다. 예를 들어 var divCode = '<div data-title="' + escapeHTML('Jerry "Bull" Winston') + '">Div content</div>'잘못된 HTML이 생성됩니다!
izogfif

17

더 나은 솔루션을 찾는 것이 흥미로 웠습니다.

var escapeHTML = function(unsafe) {
  return unsafe.replace(/[&<"']/g, function(m) {
    switch (m) {
      case '&':
        return '&amp;';
      case '<':
        return '&lt;';
      case '"':
        return '&quot;';
      default:
        return '&#039;';
    }
  });
};

>결과에서 XML / HTML 코드를 손상시키지 않기 때문에 구문 분석 하지 않습니다.

벤치 마크는 다음과 같습니다. http://jsperf.com/regexpairs 또한 범용 escape기능을 만들었습니다 . http://jsperf.com/regexpairs2


1
스위치를 사용하는 것이 맵보다 훨씬 빠르다는 점이 흥미 롭습니다. 나는 이것을 기대하지 않았다! 공유해 주셔서 감사합니다!
Peter T.

가능한 코드 및 고려할 수있는 것보다 더 많은 유니 코드 문자가 있습니다. 이 수동 방법을 전혀 권장하지 않습니다.
vsync 2018 년

멀티 바이트 문자를 전혀 사용하지 않는 이유는 무엇입니까? 어디서나 UTF-8을 사용하십시오.
Neonit

4
건너 뛰기> 코드가 손상 될 수 있습니다. <> 내부도 html이라는 점을 명심해야합니다. 이 경우 건너 뛰기>가 중단됩니다. 태그 사이에서만 이스케이프하는 경우 이스케이프 <및 & 만 필요합니다.
jgmjgm

8

인코딩되지 않은 텍스트를 표시하는 가장 간결하고 성능이 좋은 방법은 textContent속성 을 사용하는 것 입니다.

사용하는 것보다 빠릅니다innerHTML . 그리고 이스케이프 오버 헤드를 고려하지 않습니다.

document.body.textContent = 'a <b> c </b>';


@ZzZombo, 스타일 및 스크립트 태그에서 작동하지 않는 것은 완전히 정상입니다. 컨텐츠를 추가 할 때 text가 아닌 code 를 추가 하고이 경우 innerHTML을 사용하십시오. 또한 이스케이프 할 필요가 없습니다. HTML로 구문 분석되지 않은 두 개의 특수 태그입니다. 구문 분석시 컨텐츠는 닫는 순서 가 충족 될 때까지 텍스트로 처리됩니다 . </
사용자

6

DOM Elements는 innerText 에 할당하여 텍스트를 HTML로 변환하는 것을 지원합니다 . innerText는 함수가 아니지만 텍스트를 이스케이프 한 것처럼 할당하는 기능입니다.

document.querySelectorAll('#id')[0].innerText = 'unsafe " String >><>';

1
최소한 Chrome <br>에서 여러 줄로 된 텍스트를 할당 하면 줄 바꿈 대신 요소가 추가 되어 스타일이나 스크립트와 같은 특정 요소가 손상 될 수 있습니다. 은 createTextNode이 문제에 대한 경향이 없습니다.
ZzZombo

1
innerText레거시 / 사양 문제가 있습니다. 사용하는 것이 좋습니다 textContent.
Roy Tinker

3

문자열의 모든 문자를 인코딩 할 수 있습니다.

function encode(e){return e.replace(/[^]/g,function(e){return"&#"+e.charCodeAt(0)+";"})}

또는 다음과 같이 (&, inebreaks, <,>, "및 ') 걱정할 주요 문자를 타겟팅하십시오.

function encode(r){
return r.replace(/[\x26\x0A\<>'"]/g,function(r){return"&#"+r.charCodeAt(0)+";"})
}

test.value=encode('How to encode\nonly html tags &<>\'" nice & fast!');

/*************
* \x26 is &ampersand (it has to be first),
* \x0A is newline,
*************/
<textarea id=test rows="9" cols="55">&#119;&#119;&#119;&#46;&#87;&#72;&#65;&#75;&#46;&#99;&#111;&#109;</textarea>


자신의 탈출 함수를 작성하는 것은 일반적으로 나쁜 생각입니다. 이와 관련하여 다른 답변이 더 좋습니다.
jannis

2

하나의 라이너 (ES6 + 용) :

var escapeHtml = s => (s + '').replace(/[&<>"']/g, m => ({
    '&': '&amp;', '<': '&lt;', '>': '&gt;',
    '"': '&quot;', "'": '&#39;'
})[m]);

이전 버전의 경우 :

function escapeHtml(s) {
    return (s + '').replace(/[&<>"']/g, function (m) {
        return ({
            '&': '&amp;', '<': '&lt;', '>': '&gt;',
            '"': '&quot;', "'": '&#39;'
        })[m];
    });
}

0

DOM 구조를 만들 때이 문제가 발생했습니다. 이 질문은 그것을 해결하는 데 도움이되었습니다. 이중 쉐브론을 경로 구분 기호로 사용하고 싶었지만 새 텍스트 노드를 직접 추가하면 문자 자체가 아닌 이스케이프 된 문자 코드가 표시되었습니다.

var _div = document.createElement('div');
var _separator = document.createTextNode('&raquo;');
//_div.appendChild(_separator); /* this resulted in '&raquo;' being displayed */
_div.innerHTML = _separator.textContent; /* this was key */

0

앱에서 이미 모듈을 사용하고 있다면 escape-html 모듈을 사용할 수 있습니다 .

import escapeHtml from 'escape-html';
const unsafeString = '<script>alert("XSS");</script>';
const safeString = escapeHtml(unsafeString);


-4

이 솔루션을 생각해 냈습니다.

사용자 또는 데이터베이스의 안전하지 않은 데이터로 요소에 html을 추가한다고 가정 해 봅시다.

var unsafe = 'some unsafe data like <script>alert("oops");</script> here';

var html = '';
html += '<div>';
html += '<p>' + unsafe + '</p>';
html += '</div>';

element.html(html);

XSS 공격에 대해 안전하지 않습니다. 이제 이것을 추가하십시오.

$(document.createElement('div')).html(unsafe).text();

그래서

var unsafe = 'some unsafe data like <script>alert("oops");</script> here';

var html = '';
html += '<div>';
html += '<p>' + $(document.createElement('div')).html(unsafe).text(); + '</p>';
html += '</div>';

element.html(html);

나에게 이것은 사용 .replace()하는 것 보다 훨씬 쉽고 제거 할 것입니다 !!! 가능한 모든 HTML 태그 (희망).


이것은 위험한 생각입니다. 요소가 DOM에 첨부 된 경우 안전하지 않은 HTML 문자열을 HTML로 구문 분석합니다. 대신 .innerText를 사용하십시오.
teknopaul

안전하지 않습니다. 로 변환 &lt;script&gt;됩니다 <script>.
fgb
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.