programing

HTML 엔티티 디코드

copysource 2022. 9. 22. 22:55
반응형

HTML 엔티티 디코드

JavaScript 또는 JQuery를 사용하여 HTML 엔티티를 인코딩 및 디코딩하려면 어떻게 해야 합니까?

var varTitle = "Chris' corner";

나는 다음과 같이 되길 바란다.

var varTitle = "Chris' corner";

답변으로 받아들여진 jQuery 코드를 사용하지 않는 것이 좋습니다.페이지에 디코딩할 문자열은 삽입하지 않지만 스크립트나 HTML 요소 등이 생성됩니다.이건 우리가 필요로 하는 것보다 훨씬 많은 암호야.그 대신 보다 안전하고 최적화된 기능을 사용하는 것이 좋습니다.

var decodeEntities = (function() {
  // this prevents any overhead from creating the object each time
  var element = document.createElement('div');

  function decodeHTMLEntities (str) {
    if(str && typeof str === 'string') {
      // strip script/html tags
      str = str.replace(/<script[^>]*>([\S\s]*?)<\/script>/gmi, '');
      str = str.replace(/<\/?\w(?:[^"'>]|"[^"]*"|'[^']*')*>/gmi, '');
      element.innerHTML = str;
      str = element.textContent;
      element.textContent = '';
    }

    return str;
  }

  return decodeHTMLEntities;
})();

http://jsfiddle.net/LYteC/4/

이 기능을 사용하려면 전화만 하면 됩니다.decodeEntities("&amp;")또한 jQuery 버전과 동일한 기본 기술을 사용합니다. 단, jQuery의 오버헤드는 없고 입력의 HTML 태그를 삭제한 후입니다.HTML 태그를 필터링하는 방법은 승인된 답변에 대한 Mike Samuel의 의견을 참조하십시오.

이 함수는 프로젝트에 다음 행을 추가하여 jQuery 플러그인으로 쉽게 사용할 수 있습니다.

jQuery.decodeEntities = decodeEntities;

다음과 같은 작업을 수행할 수 있습니다.

var Title = $('<textarea />').html("Chris&apos; corner").text();
console.log(Title);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

JS 바이올린

보다 인터랙티브한 버전:

$('form').submit(function() {
  var theString = $('#string').val();
  var varTitle = $('<textarea />').html(theString).text();
  $('#output').text(varTitle);
  return false;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form action="#" method="post">
  <fieldset>
    <label for="string">Enter a html-encoded string to decode</label>
    <input type="text" name="string" id="string" />
  </fieldset>
  <fieldset>
    <input type="submit" value="decode" />
  </fieldset>
</form>

<div id="output"></div>

JS 바이올린

Robert K가 말한 것처럼 사용자 입력이 DOM에 액세스해서는 안 되기 때문에 위험하므로 jQuery.html().text()를 사용하여 html 엔티티를 디코딩하지 마십시오.이것이 안전하지 않은 이유에 대해서는 XSS에 대해 읽어보십시오.

대신 Underscore.js 유틸리티 벨트라이브러리에는 이스케이프 및 에스케이프 해제 방법이 포함되어 있습니다.

_.cring(문자열)

HTML에 삽입하기 위해 문자열을 이스케이프하여 바꿉니다.&,<,>,",`,그리고.'성격.

_.escape('Curly, Larry & Moe');
=> "Curly, Larry &amp; Moe"

_.unescape(문자열)

탈출의 반대말이야, 대신해서&amp;,&lt;,&gt;,&quot;,&#96;그리고.&#x27;탈출하지 않은 상대들과 함께요

_.unescape('Curly, Larry &amp; Moe');
=> "Curly, Larry & Moe"

더 많은 문자 디코딩을 지원하려면 언더스코어 unescape 메서드를 복사하고 더 많은 문자를 맵에 추가합니다.

원저작자는 여기서 대답합니다.

이것은 HTML 문자를 해독하는 가장 좋아하는 방법입니다.이 코드를 사용하는 장점은 태그도 유지된다는 것입니다.

function decodeHtml(html) {
    var txt = document.createElement("textarea");
    txt.innerHTML = html;
    return txt.value;
}

예: http://jsfiddle.net/k65s3/

입력:

Entity:&nbsp;Bad attempt at XSS:<script>alert('new\nline?')</script><br>

출력:

Entity: Bad attempt at XSS:<script>alert('new\nline?')</script><br>

다음은 div를 만들지 않고 "가장 일반적인" HTML 이스케이프 문자를 디코딩하는 빠른 방법입니다.

function decodeHTMLEntities(text) {
    var entities = [
        ['amp', '&'],
        ['apos', '\''],
        ['#x27', '\''],
        ['#x2F', '/'],
        ['#39', '\''],
        ['#47', '/'],
        ['lt', '<'],
        ['gt', '>'],
        ['nbsp', ' '],
        ['quot', '"']
    ];

    for (var i = 0, max = entities.length; i < max; ++i) 
        text = text.replace(new RegExp('&'+entities[i][0]+';', 'g'), entities[i][1]);

    return text;
}

다음은 다른 버전입니다.

function convertHTMLEntity(text){
    const span = document.createElement('span');

    return text
    .replace(/&[#A-Za-z0-9]+;/gi, (entity,position,text)=> {
        span.innerHTML = entity;
        return span.innerText;
    });
}

console.log(convertHTMLEntity('Large &lt; &#163; 500'));

Robert K의 솔루션에서 영감을 얻은 이 버전은 HTML 태그를 제거하지 않고 안전합니다.

var decode_entities = (function() {
    // Remove HTML Entities
    var element = document.createElement('div');

    function decode_HTML_entities (str) {

        if(str && typeof str === 'string') {

            // Escape HTML before decoding for HTML Entities
            str = escape(str).replace(/%26/g,'&').replace(/%23/g,'#').replace(/%3B/g,';');

            element.innerHTML = str;
            if(element.innerText){
                str = element.innerText;
                element.innerText = '';
            }else{
                // Firefox support
                str = element.textContent;
                element.textContent = '';
            }
        }
        return unescape(str);
    }
    return decode_HTML_entities;
})();

jQuery는 html 엔티티를 인코딩 및 디코딩하는 방법을 제공합니다.

<div/> 태그를 사용하면 모든 html이 삭제됩니다.

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

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

"<textarea/>" 태그를 사용하면 html 태그가 유지됩니다.

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

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

목록에 "Robert K에서 영감을 받은" 다른 버전을 추가하기 위해 HTML 태그를 제거하지 않는 안전한 버전이 있습니다.HTML 파서를 통해 문자열 전체를 실행하는 대신 엔티티만 추출하여 변환합니다.

var decodeEntities = (function() {
    // this prevents any overhead from creating the object each time
    var element = document.createElement('div');

    // regular expression matching HTML entities
    var entity = /&(?:#x[a-f0-9]+|#[0-9]+|[a-z0-9]+);?/ig;

    return function decodeHTMLEntities(str) {
        // find and replace all the html entities
        str = str.replace(entity, function(m) {
            element.innerHTML = m;
            return element.textContent;
        });

        // reset the value
        element.textContent = '';

        return str;
    }
})();

Robert K의 솔루션에서 영감을 얻어 HTML 태그를 삭제하고 다음과 같은 스크립트 및 이벤트 핸들러를 실행하지 않도록 합니다.<img src=fake onerror="prompt(1)">Chrome, FF, IE(IE9)는 Chrome, FF, IE입니다.

var decodeEntities = (function () {
        //create a new html document (doesn't execute script tags in child elements)
        var doc = document.implementation.createHTMLDocument("");
        var element = doc.createElement('div');

        function getText(str) {
            element.innerHTML = str;
            str = element.textContent;
            element.textContent = '';
            return str;
        }

        function decodeHTMLEntities(str) {
            if (str && typeof str === 'string') {
                var x = getText(str);
                while (str !== x) {
                    str = x;
                    x = getText(x);
                }
                return x;
            }
        }
        return decodeHTMLEntities;
    })();

전화만 하면 됩니다.

decodeEntities('<img src=fake onerror="prompt(1)">');
decodeEntities("<script>alert('aaa!')</script>");

여기 풀버전이 있습니다.

function htmldecode(s){
    window.HTML_ESC_MAP = {
    "nbsp":" ","iexcl":"¡","cent":"¢","pound":"£","curren":"¤","yen":"¥","brvbar":"¦","sect":"§","uml":"¨","copy":"©","ordf":"ª","laquo":"«","not":"¬","reg":"®","macr":"¯","deg":"°","plusmn":"±","sup2":"²","sup3":"³","acute":"´","micro":"µ","para":"¶","middot":"·","cedil":"¸","sup1":"¹","ordm":"º","raquo":"»","frac14":"¼","frac12":"½","frac34":"¾","iquest":"¿","Agrave":"À","Aacute":"Á","Acirc":"Â","Atilde":"Ã","Auml":"Ä","Aring":"Å","AElig":"Æ","Ccedil":"Ç","Egrave":"È","Eacute":"É","Ecirc":"Ê","Euml":"Ë","Igrave":"Ì","Iacute":"Í","Icirc":"Î","Iuml":"Ï","ETH":"Ð","Ntilde":"Ñ","Ograve":"Ò","Oacute":"Ó","Ocirc":"Ô","Otilde":"Õ","Ouml":"Ö","times":"×","Oslash":"Ø","Ugrave":"Ù","Uacute":"Ú","Ucirc":"Û","Uuml":"Ü","Yacute":"Ý","THORN":"Þ","szlig":"ß","agrave":"à","aacute":"á","acirc":"â","atilde":"ã","auml":"ä","aring":"å","aelig":"æ","ccedil":"ç","egrave":"è","eacute":"é","ecirc":"ê","euml":"ë","igrave":"ì","iacute":"í","icirc":"î","iuml":"ï","eth":"ð","ntilde":"ñ","ograve":"ò","oacute":"ó","ocirc":"ô","otilde":"õ","ouml":"ö","divide":"÷","oslash":"ø","ugrave":"ù","uacute":"ú","ucirc":"û","uuml":"ü","yacute":"ý","thorn":"þ","yuml":"ÿ","fnof":"ƒ","Alpha":"Α","Beta":"Β","Gamma":"Γ","Delta":"Δ","Epsilon":"Ε","Zeta":"Ζ","Eta":"Η","Theta":"Θ","Iota":"Ι","Kappa":"Κ","Lambda":"Λ","Mu":"Μ","Nu":"Ν","Xi":"Ξ","Omicron":"Ο","Pi":"Π","Rho":"Ρ","Sigma":"Σ","Tau":"Τ","Upsilon":"Υ","Phi":"Φ","Chi":"Χ","Psi":"Ψ","Omega":"Ω","alpha":"α","beta":"β","gamma":"γ","delta":"δ","epsilon":"ε","zeta":"ζ","eta":"η","theta":"θ","iota":"ι","kappa":"κ","lambda":"λ","mu":"μ","nu":"ν","xi":"ξ","omicron":"ο","pi":"π","rho":"ρ","sigmaf":"ς","sigma":"σ","tau":"τ","upsilon":"υ","phi":"φ","chi":"χ","psi":"ψ","omega":"ω","thetasym":"ϑ","upsih":"ϒ","piv":"ϖ","bull":"•","hellip":"…","prime":"′","Prime":"″","oline":"‾","frasl":"⁄","weierp":"℘","image":"ℑ","real":"ℜ","trade":"™","alefsym":"ℵ","larr":"←","uarr":"↑","rarr":"→","darr":"↓","harr":"↔","crarr":"↵","lArr":"⇐","uArr":"⇑","rArr":"⇒","dArr":"⇓","hArr":"⇔","forall":"∀","part":"∂","exist":"∃","empty":"∅","nabla":"∇","isin":"∈","notin":"∉","ni":"∋","prod":"∏","sum":"∑","minus":"−","lowast":"∗","radic":"√","prop":"∝","infin":"∞","ang":"∠","and":"∧","or":"∨","cap":"∩","cup":"∪","int":"∫","there4":"∴","sim":"∼","cong":"≅","asymp":"≈","ne":"≠","equiv":"≡","le":"≤","ge":"≥","sub":"⊂","sup":"⊃","nsub":"⊄","sube":"⊆","supe":"⊇","oplus":"⊕","otimes":"⊗","perp":"⊥","sdot":"⋅","lceil":"⌈","rceil":"⌉","lfloor":"⌊","rfloor":"⌋","lang":"〈","rang":"〉","loz":"◊","spades":"♠","clubs":"♣","hearts":"♥","diams":"♦","\"":"quot","amp":"&","lt":"<","gt":">","OElig":"Œ","oelig":"œ","Scaron":"Š","scaron":"š","Yuml":"Ÿ","circ":"ˆ","tilde":"˜","ndash":"–","mdash":"—","lsquo":"‘","rsquo":"’","sbquo":"‚","ldquo":"“","rdquo":"”","bdquo":"„","dagger":"†","Dagger":"‡","permil":"‰","lsaquo":"‹","rsaquo":"›","euro":"€"};
    if(!window.HTML_ESC_MAP_EXP)
        window.HTML_ESC_MAP_EXP = new RegExp("&("+Object.keys(HTML_ESC_MAP).join("|")+");","g");
    return s?s.replace(window.HTML_ESC_MAP_EXP,function(x){
        return HTML_ESC_MAP[x.substring(1,x.length-1)]||x;
    }):s;
}

사용.

htmldecode("&sum;&nbsp;&gt;&euro;");

신뢰할 수 없는 HTML을 페이지에 삽입하는 것은 "jQuery를 사용하여 HTML 엔티티를 디코딩하는 방법"에서 설명한 바와 같이 위험합니다.

하나의 대안은 자바스크립트만의 구현으로 PHP의 html_html_html을 사용하는 것입니다(http://phpjs.org/functions/html_entity_decode:424)).예를 들어 다음과 같습니다.

var varTitle = html_entity_decode("Chris&apos; corner");

@William Lahti의 답변에 대한 보다 기능적인 접근법:

var entities = {
  'amp': '&',
  'apos': '\'',
  '#x27': '\'',
  '#x2F': '/',
  '#39': '\'',
  '#47': '/',
  'lt': '<',
  'gt': '>',
  'nbsp': ' ',
  'quot': '"'
}

function decodeHTMLEntities (text) {
  return text.replace(/&([^;]+);/gm, function (match, entity) {
    return entities[entity] || match
  })
}

@Robert K와 @matcasey는 둘 다 좋은 코드를 가지고 있기 때문에 앞으로 누구나 사용할 수 있도록 이곳에서 CoffeeScript 버전을 제공하고 싶다고 생각했습니다.

    String::unescape = (strict = false) ->
      ###
      # Take escaped text, and return the unescaped version
      #
      # @param string str | String to be used
      # @param bool strict | Stict mode will remove all HTML
      #
      # Test it here:
      # https://jsfiddle.net/tigerhawkvok/t9pn1dn5/
      #
      # Code: https://gist.github.com/tigerhawkvok/285b8631ed6ebef4446d
      ###
      # Create a dummy element
      element = document.createElement("div")
      decodeHTMLEntities = (str) ->
        if str? and typeof str is "string"
          unless strict is true
            # escape HTML tags
            str = escape(str).replace(/%26/g,'&').replace(/%23/g,'#').replace(/%3B/g,';')
          else
            str = str.replace(/<script[^>]*>([\S\s]*?)<\/script>/gmi, '')
            str = str.replace(/<\/?\w(?:[^"'>]|"[^"]*"|'[^']*')*>/gmi, '')
          element.innerHTML = str
          if element.innerText
            # Do we support innerText?
            str = element.innerText
            element.innerText = ""
          else
            # Firefox
            str = element.textContent
            element.textContent = ""
        unescape(str)
      # Remove encoded or double-encoded tags
      fixHtmlEncodings = (string) ->
        string = string.replace(/\&amp;#/mg, '&#') # The rest, for double-encodings
        string = string.replace(/\&quot;/mg, '"')
        string = string.replace(/\&quote;/mg, '"')
        string = string.replace(/\&#95;/mg, '_')
        string = string.replace(/\&#39;/mg, "'")
        string = string.replace(/\&#34;/mg, '"')
        string = string.replace(/\&#62;/mg, '>')
        string = string.replace(/\&#60;/mg, '<')
        string
      # Run it
      tmp = fixHtmlEncodings(this)
      decodeHTMLEntities(tmp)

https://jsfiddle.net/tigerhawkvok/t9pn1dn5/7/ 또는 https://gist.github.com/tigerhawkvok/285b8631ed6ebef4446d을 참조하십시오(컴파일된 JS가 포함되어 있으며 이 답변과 비교하여 업데이트될 수 있습니다).

게임에 조금 늦은 건 알지만, jQuery를 사용하여 HTML 엔티티를 디코딩하는 방법의 예로서 다음과 같은 스니펫을 제공하려고 합니다.

var varTitleE = "Chris&apos; corner";
var varTitleD = $("<div/>").html(varTitleE).text();

console.log(varTitleE + " vs. " + varTitleD);​​​​​​​​​​​

콘솔 결과를 보려면 인스펙터/firebug 부팅을 잊지 마십시오.또는 단순히 console.log(...)를 alert(...)로 대체하십시오.

Google Chrome 검사기를 통해 콘솔에 다음과 같이 표시됩니다.

Chris&apos; corner vs. Chris' corner

jquery 또는 모든 것을 사전에 정의하지 않고 순수한 javascript로 하려면 인코딩된html 문자열을 내부 요소를 통해 사이클링합니다.필요한 모든 디코드 단계에 대한 HTML 및 innerText(/textContent) 속성:

<html>
  <head>
    <title>For every decode step, cycle through innerHTML and innerText </title>
    <script>
function decode(str) {
  var d = document.createElement("div");
  d.innerHTML = str; 
  return typeof d.innerText !== 'undefined' ? d.innerText : d.textContent;
}
    </script>
  </head>
  <body>
    <script>
var encodedString = "&lt;p&gt;name&lt;/p&gt;&lt;p&gt;&lt;span style=\"font-size:xx-small;\"&gt;ajde&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;da&lt;/em&gt;&lt;/p&gt;";
    </script>
    <input type=button onclick="document.body.innerHTML=decode(encodedString)"/>
  </body>
</html>

나는 그것이 선택한 해결책과는 정반대라고 생각한다.

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

시험해 보세요:)

언급URL : https://stackoverflow.com/questions/5796718/html-entity-decode

반응형