Javascript에서 HTML 엔티티를 이스케이프 처리 하시겠습니까?

XML-RPC 백엔드와 통신하는 Javascript 코드가 있습니다. XML-RPC는 다음 형식의 문자열을 반환합니다.

<img src='myimage.jpg'>

그러나 Javascript를 사용하여 문자열을 HTML에 삽입하면 문자 그대로 렌더링됩니다. 이미지가 보이지 않고 문자 그대로 문자열이 표시됩니다.

<img src='myimage.jpg'>

내 생각 엔 HTML-RPC 채널을 통해 HTML이 이스케이프되고 있다고 생각합니다.

Javascript에서 문자열을 이스케이프 해제하려면 어떻게해야합니까? 이 페이지의 기술을 실패했습니다. http://paulschreiber.com/blog/2008/09/20/javascript-how-to-unescape-html-entities/

문제를 진단하는 다른 방법은 무엇입니까?



답변

편집 : Wladimir가 제안한 대로 DOMParser API를 사용해야 합니다. 게시 된 함수에 보안 취약점이 도입 되었으므로 이전 답변을 편집했습니다.

다음 스 니펫은 약간 수정 된 이전 답변의 코드입니다. textarea 대신 divXSS 취약성을 대신 IE9 및 Firefox에서 여전히 문제가됩니다.

function htmlDecode(input){
  var e = document.createElement('textarea');
  e.innerHTML = input;
  // handle case of empty input
  return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue;
}

htmlDecode("&lt;img src='myimage.jpg'&gt;");
// returns "<img src='myimage.jpg'>"

기본적으로 프로그래밍 방식으로 DOM 요소를 만들고, 인코딩 된 HTML을 innerHTML에 할당하고 innerHTML 삽입에서 생성 된 텍스트 노드에서 nodeValue를 검색합니다. 요소를 만들지 만 추가하지 않기 때문에 사이트 HTML은 수정되지 않습니다.

크로스 브라우저 (이전 브라우저 포함)에서 작동하며 모든 브라우저를 수락합니다. HTML 문자 엔티티를 .

편집 :이 코드의 이전 버전은 IE에서 공백 입력이 작동하지 않았습니다. jsFiddle (IE에서보기)에서 . 위의 버전은 모든 입력에서 작동합니다.

업데이트 : 이것은 큰 문자열에서 작동하지 않으며 보안 취약점을 유발합니다. 의견을 참조하십시오.


답변

여기에 주어진 대부분의 답변에는 큰 단점이 있습니다. 변환하려는 문자열을 신뢰할 수 없으면 XSS (Cross-Site Scripting) 취약점이 생깁니다 . 허용되는 답변 의 기능에 대해 다음을 고려하십시오.

htmlDecode("<img src='dummy' onerror='alert(/xss/)'>");

여기의 문자열에는 이스케이프 처리되지 않은 HTML 태그가 포함되어 있으므로 아무것도 디코딩하는 대신 htmlDecode함수는 실제로 문자열 내에 지정된 JavaScript 코드를 실행합니다.

모든 최신 브라우저 에서 지원되는 DOMParser 를 사용하면이를 피할 수 있습니다 .

function htmlDecode(input) {
  var doc = new DOMParser().parseFromString(input, "text/html");
  return doc.documentElement.textContent;
}

console.log(  htmlDecode("&lt;img src='myimage.jpg'&gt;")  )
// "<img src='myimage.jpg'>"

console.log(  htmlDecode("<img src='dummy' onerror='alert(/xss/)'>")  )
// ""

이 함수는 JavaScript 코드를 부작용으로 실행하지 않습니다. 모든 HTML 태그는 무시되며 텍스트 내용 만 반환됩니다.

호환성 참고 사항 : HTML을 파싱 DOMParser하려면 Chrome 30, Firefox 12, Opera 17, Internet Explorer 10, Safari 7.1 또는 Microsoft Edge가 필요합니다. 따라서 지원이없는 모든 브라우저는 EOL을 지나고 있으며 2017 년 현재 야생에서 여전히 볼 수있는 유일한 브라우저는 이전 Internet Explorer 및 Safari 버전입니다 (일반적으로 여전히 귀찮게하기에는 충분하지 않습니다).


답변

jQuery를 사용하는 경우 :

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

그렇지 않으면 기능 이 우수한 Strictly Software의 Encoder Object를 사용하십시오 htmlDecode().


답변

비결은 브라우저의 힘을 사용하여 특수 HTML 문자를 해독하지만 브라우저가 실제 HTML 인 것처럼 결과를 실행할 수 없도록하는 것입니다.이 함수는 정규식을 사용하여 인코딩 된 HTML 문자 (한 문자)를 식별하고 대체합니다. 한 번에.

function unescapeHtml(html) {
    var el = document.createElement('div');
    return html.replace(/\&[#0-9a-z]+;/gi, function (enc) {
        el.innerHTML = enc;
        return el.innerText
    });
}


답변

이스케이프를 제거하려는 HTML이 매우 길지 않고 65536자를 초과하지 않는 한 CMS의 대답은 제대로 작동합니다. Chrome에서 내부 HTML은 각각 최대 65536 개의 많은 하위 노드로 분할되므로 연결해야합니다. 이 함수는 매우 긴 문자열에도 작동합니다.

function unencodeHtmlContent(escapedHtml) {
  var elem = document.createElement('div');
  elem.innerHTML = escapedHtml;
  var result = '';
  // Chrome splits innerHTML into many child nodes, each one at most 65536.
  // Whereas FF creates just one single huge child node.
  for (var i = 0; i < elem.childNodes.length; ++i) {
    result = result + elem.childNodes[i].nodeValue;
  }
  return result;
}

자세한 내용은 innerHTML최대 길이에 대한 이 답변을 참조하십시오 : https : //.com/a/27545633/694469


답변

질문에 대한 직접적인 대답은 아니지만 RPC가 해당 구조 내부의 이미지 데이터 (예 : URL)와 함께 일부 구조 (XML 또는 JSON 등)를 반환하는 것이 더 좋지 않습니까?

그런 다음 자바 스크립트에서 구문 분석하고 <img>Javascript 자체를 사용하여 빌드 할 수 있습니다.

RPC에서받는 구조는 다음과 같습니다.

{"img" : ["myimage.jpg", "myimage2.jpg"]}

외부 소스에서 오는 코드를 페이지에 삽입하는 것이 안전하지 않기 때문에이 방법이 더 낫습니다. 누군가 XML-RPC 스크립트를 가로 채서 원하지 않는 것을 (아마도 일부 자바 스크립트 …)


답변

크리스의 대답은 훌륭하고 우아하지만 가치가 정의되지 않으면 실패합니다 . 단순한 개선만으로도 견고 해집니다.

function htmlDecode(value) {
   return (typeof value === 'undefined') ? '' : $('<div/>').html(value).text();
}


답글 남기기