javascript - HTML 實體解碼
我如何使用 JavaScript 或 JQuery 編碼和解碼 HTML 實體?
var varTitle = "Chris' corner";
我希望它是:
var varTitle = "Chris' corner";
答案#1
我不建議使用被接受為答案的 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("&"),它將使用與 jQuery 版本相同的底層技術——但沒有 jQuery 的開銷,並且會在輸入中清理 HTML 標籤。請參見 Mike Samuel 在被接受的答案中的評論,了解如何過濾 HTML 標籤。
這個功能可以很容易地作為 jQuery 插件使用,只需在你的專案中加入以下這行程式碼。
jQuery.decodeEntities = decodeEntities;
答案#2
你可以試試像這樣的東西:
var Title = $('<textarea />').html("Chris' corner").text();
console.log(Title);<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>JS Fiddle。
一個更互動的版本:
$('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 Fiddle。
答案#3
編輯 2023:如今你應該使用像 he 這樣的函式庫。 :
就像 Robert K 說的,不要使用 jQuery.html().text() 來解碼 HTML 實體,因為這不安全,使用者輸入不應該有權限訪問 DOM。閱讀關於 XSS 的資料可以了解為什麼這樣不安全。
取而代之的是,嘗試使用附帶 escape 和 unescape 方法的 Underscore.js 工具庫:
_.escape(字串)
將字串轉義以便插入到 HTML 中,替換 &、<、>、"、` 和 ' 字元。
_.escape('Curly, Larry & Moe');
=> "Curly, Larry & Moe"
_.unescape(string)
與轉義相反,將 &、<、>、"、` 和 ' 替換為它們未轉義的對應字符。
_.unescape('Curly, Larry & Moe');
=> "Curly, Larry & Moe"
要支援解碼更多字元,只需複製 Underscore 的 unescape 方法,並在映射中添加更多字元。
答案#4
原作者在此回答。
這是我最喜歡的解碼 HTML 字元的方式。使用這段程式碼的優點是標籤也會被保留。
function decodeHtml(html) {
var txt = document.createElement("textarea");
txt.innerHTML = html;
return txt.value;
}
範例: http://jsfiddle.net/k65s3/
輸入:
Entity: Bad attempt at XSS:<script>alert('new\nline?')</script><br>
輸出:
Entity: Bad attempt at XSS:<script>alert('new\nline?')</script><br>
答案#5
這裡有一個不需要建立 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;
}
console.log(decodeHTMLEntities('& "'));答案#6
這裡是另一個版本:
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 < £ 500'));答案#7
受到羅伯特·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;
})();
答案#8
jQuery 提供了一種編碼和解碼 HTML 實體的方法。
如果你使用 “
” 標籤,它會刪除所有的 HTML。function htmlDecode(value) {
return $("<div/>").html(value).text();
}
function htmlEncode(value) {
return $('<div/>').text(value).html();
}
如果你使用「」標籤,它將保留 HTML 標籤。
function htmlDecode(value) {
return $("<textarea/>").html(value).text();
}
function htmlEncode(value) {
return $('<textarea/>').text(value).html();
}
答案#9
為了在列表中再加上一個「受 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;
}
})();
答案#10
受到 Robert K 的解決方案啟發,去除 HTML 標籤並防止執行腳本和事件處理程序,例如:<img src=fake onerror="prompt(1)"> 已在最新的 Chrome、FF、IE 上測試(應該從 IE9 開始可用,但尚未測試)。
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>");
答案#11
這裡是一個完整版本
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("∑ >€");
答案#12
對 @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
})
}
console.log(decodeHTMLEntities('Large < £ 500'));