我可以在JavaScript中转义html特殊字符吗?

fer*_*123 164 html javascript

我想通过javascript函数向HTML显示文本.如何在JS中转义html特殊字符?有API吗?

bjo*_*rnd 282

function escapeHtml(unsafe) {
    return unsafe
         .replace(/&/g, "&")
         .replace(/</g, "&lt;")
         .replace(/>/g, "&gt;")
         .replace(/"/g, "&quot;")
         .replace(/'/g, "&#039;");
 }
Run Code Online (Sandbox Code Playgroud)

  • 因为:http://stackoverflow.com/questions/2083754/why-shouldnt-apos-be-used-to-escape-single-quotes (31认同)
  • 是否有任何标准 API 或者这是唯一的方法? (21认同)
  • @jamix您无法使用原始字符串进行全局替换,而现代浏览器引擎优化简单的正则表达式非常好. (18认同)
  • 为什么"&#039;" 而不是"" ? (11认同)
  • 请在http://stackoverflow.com/a/4835406/1432801查看更完整的答案 (8认同)
  • 我认为`replace()`调用中的正则表达式是不必要的.普通的旧单字符字符串也可以. (2认同)
  • @StepanYakovenko 用 CSS 处理效果更好。事实上,用 ` ` 替换每个空格将防止空格上的文本中断(` ` 表示“不间断空格”)。 (2认同)
  • [’ 在 HTML5 中有效,但在 HTML4 中无效](/sf/ask/145862811/#18551371) (2认同)
  • @jamix不,如果你这样做,它只会替换第一次出现的“&amp;”,第一次出现的“&lt;”等。您需要使用带有“/g”标志的正则表达式。 (2认同)

spi*_*ama 48

function escapeHtml(html){
  var text = document.createTextNode(html);
  var p = document.createElement('p');
  p.appendChild(text);
  return p.innerHTML;
}

// Escape while typing & print result
document.querySelector('input').addEventListener('input', e => {
  console.clear();
  console.log( escapeHtml(e.target.value) );
});
Run Code Online (Sandbox Code Playgroud)
<input style='width:90%; padding:6px;' placeholder='&lt;b&gt;cool&lt;/b&gt;'>
Run Code Online (Sandbox Code Playgroud)

  • 请注意,这不会转义引号(`"` 或 `'`),因此此函数中的字符串如果在 HTML 标记属性中使用,仍然可能造成损坏。 (10认同)

jer*_*ome 46

你可以使用jQuery的.text()功能.

例如:

http://jsfiddle.net/9H6Ch/

从关于.text()函数的jQuery文档:

我们需要注意,此方法会根据需要转义提供的字符串,以便在HTML中正确呈现.为此,它调用DOM方法.createTextNode(),不将字符串解释为HTML.

jQuery文档的早期版本以这种方式表达了它(强调添加):

我们需要注意,此方法会根据需要转义提供的字符串,以便在HTML中正确呈现.为此,它调用DOM方法.createTextNode(),它将特殊字符替换为其HTML实体等价物(例如< for <).

  • 请注意,这会使引号 ''' 和 '"' 未转义,这可能会让您出错 (4认同)
  • 如果您只想像这样进行转换,甚至可以在一个新元素上使用它:`const str =“ foo &lt;&gt;'\”&“;``$('&lt;div&gt;')。text(str).html( )`产生`foo&lt;&gt;'“&amp;` (2认同)

lve*_*lla 25

我想我找到了正确的方法......

// Create a DOM Text node:
var text_node = document.createTextNode(unescaped_text);

// Get the HTML element where you want to insert the text into:
var elem = document.getElementById('msg_span');

// Optional: clear its old contents
//elem.innerHTML = '';

// Append the text node into it:
elem.appendChild(text_node);
Run Code Online (Sandbox Code Playgroud)

  • 请注意,如果您尝试像这样访问文本节点的内容,则不会对其进行转义:`document.createTextNode("&lt;script&gt;alert('Attack!')&lt;/script&gt;").textContent` (3认同)

cs0*_*s01 24

使用lodash

_.escape('fred, barney, & pebbles');
// => 'fred, barney, &amp; pebbles'
Run Code Online (Sandbox Code Playgroud)

源代码

  • 下划线中的相同功能:https://underscorejs.org/#escape &amp; https://underscorejs.org/#unescape (3认同)

arj*_*pat 21

到目前为止,这是我见过它的最快方式.此外,它可以在不添加,删除或更改页面上的元素的情况下完成所有操作.

function escapeHTML(unsafeText) {
    let div = document.createElement('div');
    div.innerText = unsafeText;
    return div.innerHTML;
}
Run Code Online (Sandbox Code Playgroud)

  • 警告:它不会转义引号,因此您不能在HTML代码中的属性值内部使用输出。例如`var divCode ='&lt;div data-title =“'+ escapeHTML('Jerry” Bull“ Winston')+'”&gt; Div content &lt;/ div&gt;'`将产生无效的HTML! (2认同)

adj*_*nks 12

按书本

编辑 HTML 属性时,请使用推荐的“HTML 属性编码”:

OWASP 建议“除字母数字字符外,[您应该]使用格式&#xHH;(或命名实体,如果可用)对 ASCII 值小于 256 的所有字符进行转义,以防止切换出[an]属性。”

所以这里有一个函数可以做到这一点,并带有一个用法示例:

function escapeHTML(unsafe) {
  return unsafe.replace(
    /[\u0000-\u002F\u003A-\u0040\u005B-\u0060\u007B-\u00FF]/g,
    c => '&#' + ('000' + c.charCodeAt(0)).slice(-4) + ';'
  )
}

document.querySelector('div').innerHTML =
  '<span class=' +
  escapeHTML('"fakeclass" onclick="alert("test")') +
  '>' +
  escapeHTML('<script>alert("inspect the attributes")\u003C/script>') +
  '</span>'
Run Code Online (Sandbox Code Playgroud)
<div></div>
Run Code Online (Sandbox Code Playgroud)

您应该验证我提供的实体范围,以自行验证该功能的安全性。您还可以使用此正则表达式,它具有更好的可读性,并且应该涵盖相同的字符代码,但在我的浏览器中性能降低了约 10%:

/(?![0-9A-Za-z])[\u0000-\u00FF]/g

在 之间编辑 HTML 内容时<tags>,请使用“HTML Entity Encoding”:

为此,OWASP 建议您“查看 .textContent 属性,因为它是一个安全接收器,并且会自动进行 HTML 实体编码”。


ieg*_*gik 11

找到更好的解决方案很有意思:

var escapeHTML = function(unsafe) {
  return unsafe.replace(/[&<"']/g, function(m) {
    switch (m) {
      case '&':
        return '&amp;';
      case '<':
        return '&lt;';
      case '"':
        return '&quot;';
      default:
        return '&#039;';
    }
  });
};
Run Code Online (Sandbox Code Playgroud)

我不解析,>因为它不会破坏结果中的XML/HTML代码.

以下是基准:http://jsperf.com/regexpairs 此外,我创建了一个通用escape功能:http://jsperf.com/regexpairs2

  • 跳过 &gt; 可能会破坏代码。你必须记住,&lt;&gt;里面也是html。在这种情况下,跳过 &gt; 将会中断。如果您只是在标签之间转义,那么您可能只需要转义 &lt; 和 &amp; 。 (6认同)

use*_*ser 7

显示未编码文本的最简洁,最高效的方法是使用textContentproperty。

比使用更快innerHTML。而且这还没有考虑到转义开销。

document.body.textContent = 'a <b> c </b>';
Run Code Online (Sandbox Code Playgroud)


Dav*_*own 6

您可以对字符串中的每个字符进行编码:

function encode(e){return e.replace(/[^]/g,function(e){return"&#"+e.charCodeAt(0)+";"})}
Run Code Online (Sandbox Code Playgroud)

或者只针对需要担心的主要角色 (&、inebreaks、<、>、" 和 '),例如:

function encode(e){return e.replace(/[^]/g,function(e){return"&#"+e.charCodeAt(0)+";"})}
Run Code Online (Sandbox Code Playgroud)
function encode(r){
return r.replace(/[\x26\x0A\<>'"]/g,function(r){return"&#"+r.charCodeAt(0)+";"})
}

test.value=encode('How to encode\nonly html tags &<>\'" nice & fast!');

/*************
* \x26 is &ampersand (it has to be first),
* \x0A is newline,
*************/
Run Code Online (Sandbox Code Playgroud)


tek*_*aul 5

DOM元素通过分配给innerText支持将文本转换为HTML 。innerText不是函数,但是对其进行分配就像将文本转义一样。

document.querySelectorAll('#id')[0].innerText = 'unsafe " String >><>';
Run Code Online (Sandbox Code Playgroud)