javascript - 한글깨짐 - 입력 필드에서 속성을 읽을 때 HTML 인코딩이 손실됩니다.




한글깨짐 복구 (16)

FWIW, 인코딩이 손실되지 않습니다. 인코딩은 페이지로드 중에 마크 업 구문 분석기 (브라우저)에서 사용됩니다. 소스가 읽히고 파싱되고 브라우저에 DOM이 메모리에로드되면 인코딩이 표현 된 내용으로 파싱됩니다. 따라서 JS가 메모리에있는 모든 것을 읽으려고 할 때, 인코딩은 인코딩이 나타내는 것입니다.

여기서 의미론을 엄격히 적용 할 수도 있지만 인코딩 목적을 이해하기를 바랍니다. "잃어버린"이라는 단어는 마치 정상적으로 작동하지 않는 것처럼 들리게 만듭니다.

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

예를 들어,

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

끌어들이다

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

일부 jQuery를 통해 숨겨진 필드에서 값을 가져옵니다 (이 시점에서 인코딩이 손실 됨).

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

문제는 내가 chalk &amp; cheese 숨겨진 필드의 chalk &amp; cheese 는 JavaScript가 인코딩을 잃어 버리는 것 같습니다. " and " 를 이스케이프하려면 인코딩을 유지하고 싶습니다.

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


Jquery없이 더 빠릅니다. 문자열의 모든 문자를 인코딩 할 수 있습니다.

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

아니면 (&, inebreaks, <,>, and와 같은) 걱정할 주인공을 다음과 같이 타겟팅하십시오.

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

test.value=encode('Encode HTML entities!\n\n"Safe" escape <script id=\'\'> & useful in <pre> tags!');

testing.innerHTML=test.value;

/*************
* \x26 is &ampersand (it has to be first),
* \x0A is newline,
*************/
<textarea id=test rows="9" cols="55"></textarea>

<div id="testing">www.WHAK.com</div>


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

장고에서 탈출 templatetag을 기반으로, 내가 많이 사용 / 테스트 이미 것 같아요, 나는 필요한 것을이 기능을했다.

논란의 여지는 있지만 여백 제거 문제에 대한 대안보다 더 간단하고 (아마도 더 빠를 수도 있습니다.) 예를 들어 애트리뷰트 값 내에서 결과를 사용할 경우 필수적인 따옴표를 인코딩합니다.

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

위의 내장 체인에 동일한 결과 문자열을 제공합니다. 누군가가 왜 더 빨라 졌는지 설명 할 수 있다면 정말 행복 할거야!?

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

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

나는 (4 년 후) Django가 여전히이 중 하나를 수행하지 않는다는 것을 알아 차릴 것이다. 그래서 나는 그들이 얼마나 중요한지 잘 모르겠다.
https://github.com/django/django/blob/1.8b1/django/utils/html.py#L44

업데이트 2016-04-06 :
/ 슬래시를 이스케이프하고 싶을 수도 있습니다. 올바른 HTML 인코딩에는 필요하지 않지만 반 XSS 안전 조치로 OWASP 에서 권장합니다 . (@JNF에게 감사의 말로이 제안에 대한 감사)

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

jQuery를 사용하려는 경우. 나는 이것을 찾았다:

http://www.jquerysdk.com/api/jQuery.htmlspecialchars

(jQuery SDK에서 제공하는 jquery.string 플러그인의 일부)

Prototype의 문제점은 자바 스크립트에서 기본 객체를 확장하고 사용했을 수있는 jQuery와 호환되지 않는다는 것입니다. 물론 jQuery가 아니라 Prototype을 이미 사용하고 있다면 문제가되지 않습니다.

편집 : 또한 프로토 타입의 jQuery에 대한 문자열 유틸리티 포트입니다.

http://stilldesigning.com/dotstring/


나는 다음과 같은 기능을 사용한다.

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

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

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

htmlEncode 함수에서 요소의 innerText 를 설정하고 인코딩 된 innerHTML 검색합니다. htmlDecode 함수에서 요소의 innerHTML 값을 설정하고 innerText 가 검색됩니다.

실행중인 예제를 here 확인 here .


나는 이것이 오래된 것임을 알고 있지만 선을 제거하지 않고 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();
} 

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

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

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

데모:

산출:

스크립트:

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>

다음은 간단한 자바 스크립트 솔루션입니다. 그것은 매개 변수 또는 매개 변수없이 개체에 사용할 수있는 "HTMLEncode"메서드로 String 개체를 확장합니다.

String.prototype.HTMLEncode = function(str) {
  var result = "";
  var str = (arguments.length===1) ? str : this;
  for(var i=0; i<str.length; i++) {
     var chrcode = str.charCodeAt(i);
     result+=(chrcode>128) ? "&#"+chrcode+";" : str.substr(i,1)
   }
   return result;
}
// TEST
console.log("stetaewteaw æø".HTMLEncode());
console.log("stetaewteaw æø".HTMLEncode("æåøåæå"))

나는 요지 "자바 스크립트를위한 HTMLEncode 메서드"를 만들었습니다.


비슷한 문제가 있었고 JavaScript ( documentation )에서 encodeURIComponent 함수를 사용하여 문제를 해결했습니다.

예를 들어, 귀하가 다음을 사용하는 경우 :

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

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

당신은 chalk%20%26%20cheese 얻을 것이다. 공간조차도 유지됩니다.

내 경우에는 백 슬래시 하나를 인코딩해야하는데이 코드는 완벽하게 작동합니다.

encodeURIComponent('name/surname')

나는 name%2Fsurname 가지고있다.


여기에 다른 대답 중 일부를 사용하여 별도의 인코딩 된 문자 수 (하나의 replace() 호출)와 관계없이 한 번에 모든 관련 문자를 바꾼 버전을 만들었으므로 큰 문자열의 경우 더 빠릅니다.

DOM API가 존재하거나 다른 라이브러리에 의존하지 않습니다.

window.encodeHTML = (function() {
    function escapeRegex(s) {
        return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
    }
    var encodings = {
        '&'  : '&amp;',
        '"'  : '&quot;',
        '\'' : '&#39;',
        '<'  : '&lt;',
        '>'  : '&gt;',
        '\\' : '&#x2F;'
    };
    function encode(what) { return encodings[what]; };
    var specialChars = new RegExp('[' +
        escapeRegex(Object.keys(encodings).join('')) +
    ']', 'g');

    return function(text) { return text.replace(specialChars, encode); };
})();

한 번 실행하면 이제 전화를 걸 수 있습니다.

encodeHTML('<>&"\'')

&lt;&gt;&amp;&quot;&#39;


좋은 대답. encode 할 값이 jQuery 1.4.2에서 undefined 거나 null 과 같은 오류가 발생할 수 있습니다.

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

주어진 값을 HtmlEncodes

  var htmlEncodeContainer = $('<div />');
  function htmlEncode(value) {
    if (value) {
      return htmlEncodeContainer.text(value).html();
    } else {
      return '';
    }
  }

Prototype 에는 String 클래스가 내장되어 있습니다. 따라서 Prototype을 사용하거나 사용하려는 경우 다음과 같은 작업을 수행합니다.

'<div class="article">This is an article</div>'.escapeHTML();
// -> "&lt;div class="article"&gt;This is an article&lt;/div&gt;"


<script>
String.prototype.htmlEncode = function () {
    return String(this)
        .replace(/&/g, '&amp;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#39;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;');

}

var aString = '<script>alert("I hack your site")</script>';
console.log(aString.htmlEncode());
</script>

출력 : &lt;script&gt;alert(&quot;I hack your site&quot;)&lt;/script&gt;

.htmlEncode ()는 정의 된 모든 문자열에서 액세스 할 수 있습니다.


var htmlEnDeCode = (function() {
    var charToEntityRegex,
        entityToCharRegex,
        charToEntity,
        entityToChar;

    function resetCharacterEntities() {
        charToEntity = {};
        entityToChar = {};
        // add the default set
        addCharacterEntities({
            '&amp;'     :   '&',
            '&gt;'      :   '>',
            '&lt;'      :   '<',
            '&quot;'    :   '"',
            '&#39;'     :   "'"
        });
    }

    function addCharacterEntities(newEntities) {
        var charKeys = [],
            entityKeys = [],
            key, echar;
        for (key in newEntities) {
            echar = newEntities[key];
            entityToChar[key] = echar;
            charToEntity[echar] = key;
            charKeys.push(echar);
            entityKeys.push(key);
        }
        charToEntityRegex = new RegExp('(' + charKeys.join('|') + ')', 'g');
        entityToCharRegex = new RegExp('(' + entityKeys.join('|') + '|&#[0-9]{1,5};' + ')', 'g');
    }

    function htmlEncode(value){
        var htmlEncodeReplaceFn = function(match, capture) {
            return charToEntity[capture];
        };

        return (!value) ? value : String(value).replace(charToEntityRegex, htmlEncodeReplaceFn);
    }

    function htmlDecode(value) {
        var htmlDecodeReplaceFn = function(match, capture) {
            return (capture in entityToChar) ? entityToChar[capture] : String.fromCharCode(parseInt(capture.substr(2), 10));
        };

        return (!value) ? value : String(value).replace(entityToCharRegex, htmlDecodeReplaceFn);
    }

    resetCharacterEntities();

    return {
        htmlEncode: htmlEncode,
        htmlDecode: htmlDecode
    };
})();

ExtJS 소스 코드입니다.





html-escape-characters