[javascript] 입력 필드에서 속성을 읽을 때 HTML 인코딩이 손실 됨

숨겨진 필드에서 값을 가져 와서 텍스트 상자에 표시하기 위해 JavaScript를 사용하고 있습니다. 숨겨진 필드의 값이 인코딩됩니다.

예를 들어

<input id='hiddenId' type='hidden' value='chalk &amp; cheese' />

에 끌려

<input type='text' value='chalk &amp; cheese' />

숨겨진 필드에서 값을 얻으려면 일부 jQuery를 통해 (이 시점에서 인코딩을 잃어 버립니다).

$('#hiddenId').attr('value')

문제는 chalk &amp; cheese숨겨진 필드에서 읽을 때 JavaScript가 인코딩을 잃어버린 것 같습니다. 나는 값이되고 싶지 않다 chalk & cheese. 리터럴 amp;을 유지 하고 싶습니다 .

문자열을 HTML로 인코딩하는 JavaScript 라이브러리 또는 jQuery 메소드가 있습니까?



답변

편집 : 이 답변은 오래 전에 게시 htmlDecode되었으며이 기능은 XSS 취약점을 도입했습니다. 그것은에서 임시 요소를 변경 수정 된 divA가에 textareaXSS에서의 기회를 감소시킨다. 그러나 요즘에는 다른 답변 에서 제안한대로 DOMParser API를 사용하는 것이 좋습니다 .


나는이 기능들을 사용한다 :

function htmlEncode(value){
  // Create a in-memory element, set its inner text (which is automatically encoded)
  // Then grab the encoded contents back out. The element never exists on the DOM.
  return $('<textarea/>').text(value).html();
}

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

기본적으로 textarea 요소는 메모리에 작성되지만 문서에는 추가되지 않습니다.

htmlEncode함수 I가 설정 innerText요소, 그리고 상기 인코딩 된 검색 innerHTML; 온 htmlDecode기능이 설정 I innerHTML요소의 값과이 innerText검색된다.

여기서 실행중인 예를 확인 하십시오 .


답변

jQuery 트릭은 따옴표를 인코딩하지 않으며 IE에서는 공백을 제거합니다.

Django 의 이스케이프 템플릿 태그를 기반으로 이미 많이 사용 / 테스트 된 것으로 생각되는이 기능을 만들었습니다.

공백 제거 문제에 대한 해결 방법보다 훨씬 간단하고 빠를 수 있습니다. 예를 들어 속성 ​​값 안에 결과를 사용하려는 경우 따옴표를 인코딩합니다.

function htmlEscape(str) {
    return str
        .replace(/&/g, '&amp;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#39;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;');
}

// I needed the opposite function today, so adding here too:
function htmlUnescape(str){
    return str
        .replace(/&quot;/g, '"')
        .replace(/&#39;/g, "'")
        .replace(/&lt;/g, '<')
        .replace(/&gt;/g, '>')
        .replace(/&amp;/g, '&');
}

2013-06-17 업데이트 :
가장 빠른 탈출을 검색 하면서이replaceAll 메소드 구현을 찾았습니다 :
http://dumpsite.com/forum/index.php?topic=4.msg29#msg29
(또한 여기에서 참조 : 가장 빠름) 문자열에서 문자의 모든 인스턴스를 바꾸는 방법 )
일부 성능 결과는 다음과 같습니다.
http://jsperf.com/htmlencoderegex/25

replace위 의 내장 체인에 동일한 결과 문자열을 제공합니다 . 누군가 왜 그것이 더 빠른지 설명 할 수 있다면 매우 기쁠 것입니다!?

2015-03-04 업데이트 :
방금 AngularJS가 위의 방법을 정확하게 사용하고 있음을 알았습니다 :
https://github.com/angular/angular.js/blob/v1.3.14/src/ngSanitize/sanitize.js#L435

그들은 두 가지 세분화를 추가합니다- 모호하지 않은 모든 문자를 엔티티로 변환 할뿐만 아니라 모호한 유니 코드 문제 를 처리하는 것으로 보입니다 . 문서에 UTF8 문자 세트가 지정된 한 후자가 필요하지 않다는 인상을 받았습니다.

(4 년 후) Django는 여전히이 두 가지 중 어느 것도 수행하지 않기 때문에 이들이 얼마나 중요한지 잘 모르겠습니다.
https://github.com/django/django/blob/1.8b1/django/utils /html.py#L44

2016-04-06 업데이트 :
슬래시를 피할 수도 있습니다 /. 올바른 HTML 인코딩에는 필요하지 않지만 OWASP 에서는 XSS 안전 방지 수단으로 권장합니다 . (의견에 이것을 제안 해 주신 @JNF에게 감사드립니다)

        .replace(/\//g, '&#x2F;');


답변

다음은 jQuery .html()버전과 버전 보다 상당히 빠른 비 jQuery 버전입니다 .replace(). 이것은 모든 공백을 유지하지만 jQuery 버전과 마찬가지로 따옴표를 처리하지 않습니다.

function htmlEncode( html ) {
    return document.createElement( 'a' ).appendChild(
        document.createTextNode( html ) ).parentNode.innerHTML;
};

속도 : http://jsperf.com/htmlencoderegex/17

속도 테스트

데모: jsFiddle

산출:

산출

스크립트:

function htmlEncode( html ) {
    return document.createElement( 'a' ).appendChild(
        document.createTextNode( html ) ).parentNode.innerHTML;
};

function htmlDecode( html ) {
    var a = document.createElement( 'a' ); a.innerHTML = html;
    return a.textContent;
};

document.getElementById( 'text' ).value = htmlEncode( document.getElementById( 'hidden' ).value );

//sanity check
var html = '<div>   &amp; hello</div>';
document.getElementById( 'same' ).textContent =
      'html === htmlDecode( htmlEncode( html ) ): '
    + ( html === htmlDecode( htmlEncode( html ) ) );

HTML :

<input id="hidden" type="hidden" value="chalk    &amp; cheese" />
<input id="text" value="" />
<div id="same"></div>


답변

나는 이것이 오래된 것임을 알고 있지만 줄을 제거하지 않고 IE에서 작동 하는 허용되는 답변 의 변형을 게시하고 싶었습니다 .

function multiLineHtmlEncode(value) {
    var lines = value.split(/\r\n|\r|\n/);
    for (var i = 0; i < lines.length; i++) {
        lines[i] = htmlEncode(lines[i]);
    }
    return lines.join('\r\n');
}

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


답변

밑줄 은 이를 수행하는 방법 _.escape()_.unescape()방법을 제공합니다 .

> _.unescape( "chalk &amp; cheese" );
  "chalk & cheese"

> _.escape( "chalk & cheese" );
  "chalk &amp; cheese"


답변

좋은 대답입니다. 참고 인코딩에 값이있는 경우 undefined또는 nulljQuery를 1.4.2 당신이 오류를 같은 얻을 수 있습니다 :

jQuery("<div/>").text(value).html is not a function

또는

Uncaught TypeError: Object has no method 'html'

해결책은 실제 값을 확인하기 위해 함수를 수정하는 것입니다.

function htmlEncode(value){
    if (value) {
        return jQuery('<div/>').text(value).html();
    } else {
        return '';
    }
}


답변

평범한 자바 스크립트를 선호하는 사람들을 위해, 내가 성공적으로 사용한 방법은 다음과 같습니다.

function escapeHTML (str)
{
    var div = document.createElement('div');
    var text = document.createTextNode(str);
    div.appendChild(text);
    return div.innerHTML;
}