我有类似的字符串
var str = 'One & two & three';
由Web服务器呈现为HTML.我需要将这些字符串转换为
'One & two & three'
目前,这就是我正在做的事情(借助jQuery):
$(document.createElement('div')).html('{{ driver.person.name }}').text()
但是我有一种不安的感觉,我做错了.我试过了
unescape("&")
但它似乎不起作用,decodeURI/decodeURIComponent也没有.
有没有其他更原生和更优雅的方式呢?
您是否需要解码所有已编码的HTML实体或仅解码它们&
?
如果您只需要处理,&
那么您可以这样做:
var decoded = encoded.replace(/&/g, '&');
如果你需要解码所有HTML实体,那么你可以在没有jQuery的情况下完成:
var elem = document.createElement('textarea'); elem.innerHTML = encoded; var decoded = elem.value;
请注意Mark下面的评论,其中突出显示了本答案早期版本中的安全漏洞,并建议使用textarea
而不是div
减轻潜在的XSS漏洞.无论您使用jQuery还是纯JavaScript,都存在这些漏洞.
从JavaScript中解释HTML(文本和其他)的更现代的选项是DOMParser
API中的HTML支持(参见MDN).这允许您使用浏览器的本机HTML解析器将字符串转换为HTML文档.自2014年底以来,它已在所有主流浏览器的新版本中得到支持.
如果我们只想解码一些文本内容,我们可以将其作为文档正文中的唯一内容,解析文档,然后将其删除.body.textContent
.
var encodedStr = 'hello & world';
var parser = new DOMParser;
var dom = parser.parseFromString(
'' + encodedStr,
'text/html');
var decodedString = dom.body.textContent;
console.log(decodedString);
Matthias Bynens有一个图书馆:https://github.com/mathiasbynens/he
例:
console.log( he.decode("Jörg & Jürgen rocked to & fro ") ); // Logs "Jörg & Jürgen rocked to & fro"
我建议赞成设置元素的HTML内容然后回读其文本内容.这些方法可以起作用,但是如果在不受信任的用户输入上使用,则存在欺骗性危险并呈现XSS机会.
如果你真的不忍心加载一个库,你可以使用这个答案中textarea
描述的hack来解决一个近似重复的问题,这与我所建议的各种类似方法不同,我没有安全漏洞:
function decodeEntities(encodedString) { var textArea = document.createElement('textarea'); textArea.innerHTML = encodedString; return textArea.value; } console.log(decodeEntities('1 & 2')); // '1 & 2'
但是请注意安全问题,影响这个问题的类似方法,我在链接的答案中列出!这种方法是一种黑客攻击,未来对a textarea
(或特定浏览器中的错误)允许内容的更改可能会导致依赖于它的代码突然有一天出现XSS漏洞.
var htmlEnDeCode = (function() { var charToEntityRegex, entityToCharRegex, charToEntity, entityToChar; function resetCharacterEntities() { charToEntity = {}; entityToChar = {}; // add the default set addCharacterEntities({ '&' : '&', '>' : '>', '<' : '<', '"' : '"', ''' : "'" }); } 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的源代码.
element.innerText
也有诀窍.
如果你正在寻找它,像我一样 - 同时有一个很好的和安全的JQuery方法.
https://api.jquery.com/jquery.parsehtml/
你可以f.ex. 在您的控制台中键入:
var x = "test &"; > undefined $.parseHTML(x)[0].textContent > "test &"
因此$ .parseHTML(x)返回一个数组,如果你的文本中有HTML标记,则array.length将大于1.
您可以使用Lodash unescape /转义功能https://lodash.com/docs/4.17.5#unescape
import unescape from 'lodash/unescape'; const str = unescape('fred, barney, & pebbles');
str将成为 'fred, barney, & pebbles'
jQuery将为您编码和解码.但是,您需要使用textarea标记,而不是div.
var str1 = 'One & two & three';
var str2 = "One & two & three";
$(document).ready(function() {
$("#encoded").text(htmlEncode(str1));
$("#decoded").text(htmlDecode(str2));
});
function htmlDecode(value) {
return $("").html(value).text();
}
function htmlEncode(value) {
return $('').text(value).html();
}