我有一些与XML-RPC后端通信的JavaScript代码。 XML-RPC返回如下形式的字符串:

<img src='myimage.jpg'>

然而,当我使用JavaScript将字符串插入到HTML中时,它们会逐字呈现。我看到的不是图像,而是字符串:

<img src='myimage.jpg'>

我猜想HTML是通过XML-RPC通道转义的。

如何在JavaScript中解除字符串转义?我尝试了这个页面上的技巧,但没有成功:http://paulschreiber.com/blog/2008/09/20/javascript-how-to-unescape-html-entities/

诊断这个问题的其他方法是什么?


当前回答

对于只说一句话的男人:

const htmlDecode = innerHTML => Object.assign(document.createElement('textarea'), {innerHTML}).value;

console.log(htmlDecode('Complicated - Dimitri Vegas &amp; Like Mike'));

其他回答

要在JavaScript中解转义HTML实体*,你可以使用小型库HTML -escaper: npm install HTML -escaper

import {unescape} from 'html-escaper';

unescape('escaped string');

或从Lodash或下划线unescape函数,如果你正在使用它。


*)请注意,这些函数并不涵盖所有HTML实体,而只是最常见的,即&,<,>,',"。要解除所有HTML实体的转义,您可以使用库。

var encodedStr = 'hello &amp; world';

var parser = new DOMParser;
var dom = parser.parseFromString(
    '<!doctype html><body>' + encodedStr,
    'text/html');
var decodedString = dom.body.textContent;

console.log(decodedString);

CMS的答案很好,除非你想要取消转义的HTML非常长,超过65536个字符。因为在Chrome中,内部HTML被分割成许多子节点,每个子节点最长65536个,你需要将它们连接起来。这个函数也适用于很长的字符串:

function unencodeHtmlContent(escapedHtml) {
  var elem = document.createElement('div');
  elem.innerHTML = escapedHtml;
  var result = '';
  // Chrome splits innerHTML into many child nodes, each one at most 65536.
  // Whereas FF creates just one single huge child node.
  for (var i = 0; i < elem.childNodes.length; ++i) {
    result = result + elem.childNodes[i].nodeValue;
  }
  return result;
}

有关innerHTML最大长度的更多信息,请参阅以下答案:https://stackoverflow.com/a/27545633/694469

一个javascript解决方案,捕捉常见的:

var map = {amp: '&', lt: '<', gt: '>', quot: '"', '#039': "'"}
str = str.replace(/&([^;]+);/g, (m, c) => map[c])

这是https://stackoverflow.com/a/4835406/2738039的反面

这里给出的大多数答案都有一个巨大的缺点:如果您试图转换的字符串不受信任,那么您将以跨站点脚本(XSS)漏洞告终。对于已接受答案中的函数,考虑如下:

htmlDecode("<img src='dummy' onerror='alert(/xss/)'>");

这里的字符串包含一个未转义的HTML标记,因此htmlDecode函数将实际运行字符串中指定的JavaScript代码,而不是解码任何内容。

这可以通过使用所有现代浏览器都支持的DOMParser来避免:

html解码(输入)功能 瓦尔多克=新住户。parseFromString(输入,“短信/ html”); 归来医生。documentElement textContent; 的 控制台.log(htmlDecode(“< img src=‘myimage.jpg’>’) <img src='myimage.jpg'> ' 控制台(htmlDecode(“<img src=‘dummy’on误差=‘alert(/xss/)'>) - "

该函数保证不会运行任何JavaScript代码作为副作用。任何HTML标记将被忽略,只返回文本内容。

兼容性说明:使用DOMParser解析HTML至少需要Chrome 30、Firefox 12、Opera 17、Internet Explorer 10、Safari 7.1或Microsoft Edge。因此,所有没有支持的浏览器都已经超过了它们的EOL,截至2017年,唯一能在野外看到的是旧的Internet Explorer和Safari版本(通常这些版本仍然不够多)。