Javascript HTML实体解码

Javascript HTML实体解码,javascript,jquery,html,Javascript,Jquery,Html,如何使用JavaScript或JQuery对HTML实体进行编码和解码 var varTitle = "Chris' corner"; 我希望它是: var varTitle = "Chris' corner"; 您可以尝试以下方法: var varTitle = html_entity_decode("Chris' corner"); var Title=$('').html(“Chris'corner”).text(); 控制台日志(标题

如何使用JavaScript或JQuery对HTML实体进行编码和解码

var varTitle = "Chris' corner";
我希望它是:

var varTitle = "Chris' corner";

您可以尝试以下方法:

var varTitle = html_entity_decode("Chris' corner");
var Title=$('').html(“Chris'corner”).text();
控制台日志(标题)

将不受信任的HTML注入页面是危险的,如中所述

另一种方法是使用PHP的html_实体_解码(from)的纯JavaScript实现。然后,示例将类似于:

var varTitle = html_entity_decode("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;
})();

我知道我玩游戏有点晚了,但我想我可以提供以下代码片段作为我如何使用jQuery解码HTML实体的示例:

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

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

正如Robert K所说,不要使用jQuery.html().text()对html实体进行解码,因为这是不安全的,因为用户输入不应该访问DOM。了解这是不安全的原因

请尝试以下工具和方法提供的实用皮带库:

转义字符串以插入HTML,替换
&
`
字符

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

与escape相反的是,它取代了
“,
,&96
'及其未替换的对应项

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

要支持解码更多字符,只需复制下划线方法并向地图添加更多字符。

受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;
})();

下面是一个不需要创建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;
}
函数解码属性(文本){
var实体=[
[‘amp’、‘和’],
[apos','\''],
[#x27','\''],
[#x2F','/'],
['#39', '\''],
['#47', '/'],
[lt',''],
['nbsp',''],
['quot','“']
];
对于(变量i=0,max=entities.length;i
我认为这与所选择的解决方案正好相反

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

试试看:)

要在纯javascript中执行此操作,而无需jquery或预定义所有内容,您可以通过元素innerHTML和innerText(/textContent)属性循环编码的html字符串,以执行所需的每个解码步骤:

<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>

对于每个解码步骤,循环浏览innerHTML和innerText
函数解码(str){
var d=document.createElement(“div”);
d、 innerHTML=str;
返回d.innerText的类型!=“未定义”?d.innerText:d.textContent;
}
var encodedString=“pname/ppspan style=\”字体大小:xx小;\“ajde/span/ppemda/em/p”;

受Robert K解决方案的启发,剥离html标记并阻止执行脚本和事件处理程序,如:
在最新的Chrome、FF、IE上测试(应该可以从IE9开始工作,但尚未测试)

简单地说:

decodeEntities('<img src=fake onerror="prompt(1)">');
decodeEntities("<script>alert('aaa!')</script>");
解码实体(“”);
解码实体(“警报('aaa!'”);

jQuery提供了一种编码和解码html实体的方法

如果使用“”标记,它将删除所有html

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

function htmlEncode(value) {
    return $('<div/>').text(value).html();
}
函数htmlDecode(值){
返回$(“”).html(值).text();
}
函数htmlEncode(值){
返回$('').text(value.html();
}
如果使用“”标记,它将保留html标记

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

function htmlEncode(value) {
    return $('<textarea/>').text(value).html();
}
函数htmlDecode(值){
返回$(“”).html(值).text();
}
函数htmlEncode(值){
返回$('').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和@mattcasey都有很好的代码,我想我会在这里提供一个咖啡脚本版本,以防将来有人使用它:

    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)
String::unescape=(strict=false)->
###
#获取转义文本,并返回未转义的版本
#
#@param string str |要使用的字符串
#@param bool strict |粘贴模式将删除所有HTML
#
#在这里测试它:
# https://jsfiddle.net/tigerhawkvok/t9pn1dn5/
#
#代码:https://gist.github.com/tigerhawkvok/285b8631ed6ebef4446d
###
#创建一个虚拟元素
元素=document.createElement(“div”)
DecodeThMLentities=(str)->
如果str?和typeof str为“string”
除非严格是真的
#转义HTML标记
str=escape(str)。替换(/%26/g,,&')。替换(/%23/g,,#')。替换(/%3B/g,,;'))
其他的
str=str.replace(/]*>([\S\S]*?)/gmi',)
str=str.replace(/'))

string=string.replace(/\&60;/mg),这是一个完整的版本

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

对于@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
  })
}
var实体={
"amp":"&",
“apos”:“\”,
“#x27”:“\”,
“#x2F”:“/”,
'#39': '\'',
'#47': '/',
“lt”:”,
“nbsp”:”,
‘quot’:‘quot’
}
函数属性(文本){
返回文本。替换(/&([^;]+);/gm,函数(匹配,实体){
返回实体[实体]| |匹配
})
}

这是我最喜欢的解码HTML字符的方法。使用此代码的优点是标记也被保留

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

输入:

Entity:&nbsp;Bad attempt at XSS:<script>alert('new\nline?')</script><br>
Entity:XSS:alert的错误尝试('new\nline?')
输出:

Entity: Bad attempt at XSS:<script>alert('new\nline?')</script><br>
Entity:XSS:alert的错误尝试('new\nline?')

这里是另一个版本:

函数转换属性(文本){
const span=document.createElement('span');
返回文本
.更换(/&[#A-Za-z0-9]+;/g
function decodeHtml(html) {
    var txt = document.createElement("textarea");
    txt.innerHTML = html;
    return txt.value;
}
Entity:&nbsp;Bad attempt at XSS:<script>alert('new\nline?')</script><br>
Entity: Bad attempt at XSS:<script>alert('new\nline?')</script><br>