[javascript] jQuery를 사용하여 HTML 엔터티를 디코딩하는 방법은 무엇입니까?

jQuery를 사용하여 문자열의 HTML 엔터티를 어떻게 디코딩합니까?



답변

보안 정보 : 이 답변을 사용하면 (아래의 원래 형태로 유지됨 ) 응용 프로그램에 XSS 취약점이 발생할 수 있습니다 . 이 답변을 사용해서는 안됩니다. 이 답변의 취약점에 대한 설명은 lucascaro의 답변 을 읽고 대신 해당 답변 또는 Mark Amery의 답변을 사용하십시오.

실제로 시도해보십시오

var decoded = $("<div/>").html(encodedStr).text();


답변

jQuery없이 :

function decodeEntities(encodedString) {
  var textArea = document.createElement('textarea');
  textArea.innerHTML = encodedString;
  return textArea.value;
}

console.log(decodeEntities('1 &amp; 2')); // '1 & 2'

이것은 허용 된 답변 과 유사하게 작동 하지만 신뢰할 수없는 사용자 입력과 함께 사용하는 것이 안전합니다.


비슷한 접근 방식의 보안 문제

으로 마이크 사무엘 언급 하는 함께이 일을 <div>대신의 <textarea>신뢰할 수없는 사용자 입력하면 심지어 경우, XSS 취약점입니다 <div>DOM에 추가되지 않습니다 :

function decodeEntities(encodedString) {
  var div = document.createElement('div');
  div.innerHTML = encodedString;
  return div.textContent;
}

// Shows an alert
decodeEntities('<img src="nonexistent_image" onerror="alert(1337)">')

그러나의 공격이 <textarea>허용되는 HTML 요소가 없기 때문에이 공격은 불가능합니다 <textarea>. 결과적으로 ‘인코딩 된’문자열에 여전히 존재하는 HTML 태그는 브라우저에 의해 자동으로 엔티티 인코딩됩니다.

function decodeEntities(encodedString) {
    var textArea = document.createElement('textarea');
    textArea.innerHTML = encodedString;
    return textArea.value;
}

// Safe, and returns the correct answer
console.log(decodeEntities('<img src="nonexistent_image" onerror="alert(1337)">'))

경고 : jQuery의 사용 이렇게 .html()하고 .val()대신 사용하는 방법 .innerHTML.value, 또한 jQuery를 일부 버전에 대한 불안 *입니다 를 사용하는 경우에도textarea . 이전 버전의 jQuery는에 전달 된 문자열에 포함 된 스크립트를 일부러 명시 적으로 평가 하기 때문 .html()입니다. 따라서 다음과 같은 코드는 jQuery 1.8의 경고를 보여줍니다.

//<!-- CDATA
// Shows alert
$("<textarea>")
.html("<script>alert(1337);</script>")
.text();

//-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>

이 취약점을 잡은 Eru Penkman 에게 감사 합니다.


답변

Mike Samuel이 말했듯이 jQuery.html (). text ()를 사용하여 HTML 엔티티가 안전하지 않기 때문에 디코딩하지 마십시오.

대신 @VyvIT의 의견에서 Mustache.js 또는 decodeEntities 와 같은 템플릿 렌더러를 사용하십시오 .

Underscore.js 유틸리티 벨트 라이브러리는 escapeunescape메소드 와 함께 제공 되지만 사용자 입력에 안전하지 않습니다.

_. 탈출 (문자열)

_.unescape (문자열)


답변

텍스트와 HTML 메소드를 혼동하고 있다고 생각합니다. 이 예제를 보면 요소의 내부 HTML을 텍스트로 사용하면 디코딩 된 HTML 태그 (두 번째 버튼)가 표시됩니다. 그러나 HTML로 사용하면 HTML 형식의보기가 표시됩니다 (첫 번째 단추).

<div id="myDiv">
    here is a <b>HTML</b> content.
</div>
<br />
<input value="Write as HTML" type="button" onclick="javascript:$('#resultDiv').html($('#myDiv').html());" />
&nbsp;&nbsp;
<input value="Write as Text" type="button" onclick="javascript:$('#resultDiv').text($('#myDiv').html());" />
<br /><br />
<div id="resultDiv">
    Results here !
</div>

: 첫 번째 단추를 기록 여기에있다 HTML의 내용.

두 번째 버튼 쓰기 : <B> HTML </ B> 콘텐츠입니다.

그건 그렇고, jQuery 플러그인 에서 찾은 플러그인 -HTML 문자열을 인코딩하고 디코딩 하는 HTML 디코딩 및 인코딩 .


답변

질문은 ‘with jQuery’에 의해 제한되지만 여기에 가장 적합한 답변에 제공된 jQuery 코드는 다음을 수행한다는 것을 아는 데 도움이 될 수 있습니다 … 이는 jQuery와 함께 또는없이 작동합니다.

function decodeEntities(input) {
  var y = document.createElement('textarea');
  y.innerHTML = input;
  return y.value;
}


답변

당신은 사용할 수 있습니다 그가 에서 라이브러리를 사용할 수를 https://github.com/mathiasbynens/he

예:

console.log(he.decode("J&#246;rg &amp J&#xFC;rgen rocked to &amp; fro "));
// Logs "Jörg & Jürgen rocked to & fro"

나는 도서관의 저자 도전 의 찬성 클라이언트 측 코드에서이 라이브러리를 사용하는 어떤 이유가 여부의 문제에 <textarea>제공 해킹 다른 답변 여기에 다른 곳에서. 그는 몇 가지 정당성을 제시했다.

  • node.js 서버 측을 사용하는 경우 HTML 인코딩 / 디코딩을위한 라이브러리를 사용하면 클라이언트 측과 서버 측 모두에서 작동하는 단일 솔루션이 제공됩니다.

  • 일부 브라우저의 엔티티 디코딩 알고리즘에 버그가 있거나 일부 명명 된 문자 참조에 대한 지원이 없습니다 . 예를 들어 Internet Explorer는 깨지지 않는 공백 ( &nbsp;)을 올바르게 디코딩하고 렌더링 하지만 DOM 요소의 innerText속성을 통해 나누지 않는 공백 대신 일반 공백으로보고 하여<textarea> 해킹을 (소량이지만). 또한, IE 8, 9는 단순히 지원하지 않는 의 저자 HTML 5에 추가 된 새로운라는 문자 참조의 그는 또한에 이름을 문자 참조 지원의 테스트를 호스팅 http://mathias.html5.org/tests/html을 / named-character-references / . IE 8에서는 1,000 개가 넘는 오류를보고합니다.

    엔터티 디코딩과 관련된 브라우저 버그로부터 격리되고 /하거나 전체 범위의 명명 된 문자 참조를 처리하려면 <textarea>해킹을 피할 수 없습니다 . 와 같은 도서관이 필요합니다 .

  • 그는 이런 식으로 일을하는 것이 덜 해킹 된 것처럼 느낍니다.


답변

인코딩 :

$("<textarea/>").html('<a>').html();      // return '&lt;a&gt'

풀다:

$("<textarea/>").html('&lt;a&gt').val()   // return '<a>'