在Javascript中等效的HtmlSpecialChars?

时间:2009-11-24 01:59:20

标签: javascript html escaping html-encode

显然,这比我想象的更难找到。它甚至如此简单......

是否有一个功能相当于PHP内置于Javascript中的htmlspecialchars?我知道自己实现起来相当容易,但是如果可以的话,使用内置函数会更好。

对于那些不熟悉PHP的人,htmlspecialchars会将<htmltag/>等内容翻译成&lt;htmltag/&gt;

我知道escape()encodeURI()不会这样做。

16 个答案:

答案 0 :(得分:299)

您的解决方案代码存在问题 - 它只会逃避每个特殊字符的第一次出现。例如:

escapeHtml('Kip\'s <b>evil</b> "test" code\'s here');
Actual:   Kip&#039;s &lt;b&gt;evil</b> &quot;test" code's here
Expected: Kip&#039;s &lt;b&gt;evil&lt;/b&gt; &quot;test&quot; code&#039;s here

以下是正常运行的代码:

function escapeHtml(text) {
  return text
      .replace(/&/g, "&amp;")
      .replace(/</g, "&lt;")
      .replace(/>/g, "&gt;")
      .replace(/"/g, "&quot;")
      .replace(/'/g, "&#039;");
}

更新

以下代码将产生与上述相同的结果,但效果更好,特别是对于大块文本(感谢jbo5112)。

function escapeHtml(text) {
  var map = {
    '&': '&amp;',
    '<': '&lt;',
    '>': '&gt;',
    '"': '&quot;',
    "'": '&#039;'
  };

  return text.replace(/[&<>"']/g, function(m) { return map[m]; });
}

答案 1 :(得分:30)

那是HTML编码。没有原生的javascript函数可以做到这一点,但你可以谷歌并获得一些很好的完成。

E.g。 http://sanzon.wordpress.com/2008/05/01/neat-little-html-encoding-trick-in-javascript/

修改
这就是我测试过的:

var div = document.createElement('div');
  var text = document.createTextNode('<htmltag/>');
  div.appendChild(text);
  console.log(div.innerHTML);

输出:&lt;htmltag/&gt;

答案 2 :(得分:25)

值得一读: http://bigdingus.com/2007/12/29/html-escaping-in-javascript/

escapeHTML: (function() {
 var MAP = {
   '&': '&amp;',
   '<': '&lt;',
   '>': '&gt;',
   '"': '&#34;',
   "'": '&#39;'
 };
  var repl = function(c) { return MAP[c]; };
  return function(s) {
    return s.replace(/[&<>'"]/g, repl);
  };
})()

注意:只运行一次。并且不要在已编码的字符串上运行它,例如&amp;变为&amp;amp;

答案 3 :(得分:19)

使用jQuery可以是这样的:

var escapedValue = $('<div/>').text(value).html();

来自相关问题Escaping HTML strings with jQuery

如评论中所述,双引号和单引号保留为此实现的原样。这意味着如果您需要将element属性设置为原始html字符串,则不应使用此解决方案。

答案 4 :(得分:17)

这是一个转义HTML的函数:

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

要解码:

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

答案 5 :(得分:6)

Underscore.js为此提供了一个功能:

_.escape(string)
  
    

转义字符串以插入HTML,替换&amp;,&lt;,&gt;,&#34;和&#39;字符。

  

http://underscorejs.org/#escape

它不是内置的Javascript函数,但是如果你已经在使用Underscore,那么如果要转换的字符串不是太大,那么它就是编写自己的函数的更好选择。

答案 6 :(得分:5)

另一个目的是完全放弃所有字符映射,而是将所有不需要的字符转换为它们各自的数字字符引用,例如:

function escapeHtml(raw) {
    return raw.replace(/[&<>"']/g, function onReplace(match) {
        return '&#' + match.charCodeAt(0) + ';';
    });
}

注意指定的RegEx仅处理OP想要转义的特定字符,但是,根据将要使用转义HTML的上下文,这些字符可能不够。 Ryan Grove的文章There's more to HTML escaping than &, <, >, and "是关于这个主题的好读物。根据您的具体情况,为了避免XSS注入,可能需要以下RegEx:

var regex = /[&<>"'` !@$%()=+{}[\]]/g

答案 7 :(得分:3)

String.prototype.escapeHTML = function() {
        return this.replace(/&/g, "&amp;")
                   .replace(/</g, "&lt;")
                   .replace(/>/g, "&gt;")
                   .replace(/"/g, "&quot;")
                   .replace(/'/g, "&#039;");
    }

示例:

var toto = "test<br>";
alert(toto.escapeHTML());

答案 8 :(得分:2)

对于Node.JS用户(或在浏览器中使用Jade运行时的用户),您可以使用Jade的转义功能。

require('jade').runtime.escape(...);

如果有人在维护它,那么自己写作就没有意义。 :)

答案 9 :(得分:1)

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

下面是一个使用示例的函数:

function escapeHTML(unsafe) {
  return unsafe.replace(
    /[\u0000-\u002F]|[\u003A-\u0040]|[\u005B-\u00FF]/g,
    c => '&#' + ('000' + c.charCodeAt(0)).substr(-4, 4) + ';'
  )
}
document.querySelector('div').innerHTML =
  '<span class=' +
  escapeHTML('this should break it! " | / % * + , - / ; < = > ^') +
  '>' +
  escapeHTML('<script>alert("inspect the attributes")\u003C/script>') +
  '</span>'
<div></div>

免责声明:您应该验证我提供的用于验证安全性的实体范围。

答案 10 :(得分:0)

function htmlspecialchars(str) {
 if (typeof(str) == "string") {
  str = str.replace(/&/g, "&amp;"); /* must do &amp; first */
  str = str.replace(/"/g, "&quot;");
  str = str.replace(/'/g, "&#039;");
  str = str.replace(/</g, "&lt;");
  str = str.replace(/>/g, "&gt;");
  }
 return str;
 }

答案 11 :(得分:0)

希望这能赢得比赛,因为它的性能和最重要的不是使用.replace('&amp;','&amp;')的链式逻辑.replace('&lt;','&lt;')... < / p>

var mapObj = {
   '&':"&amp;",
   '<':"&lt;",
   '>':"&gt;",
   '"':"&quot;",
   '\'':"&#039;"
};
var re = new RegExp(Object.keys(mapObj).join("|"),"gi");

function escapeHtml(str) 
{   
    return str.replace(re, function(matched)
    {
        return mapObj[matched.toLowerCase()];
    });
}

console.log('<script type="text/javascript">alert('Hello World');</script>');
console.log(escapeHtml('<script type="text/javascript">alert('Hello World');</script>'));

答案 12 :(得分:0)

反转一句:

function decodeHtml(text) {
    return text
        .replace(/&amp;/g, '&')
        .replace(/&lt;/ , '<')
        .replace(/&gt;/, '>')
        .replace(/&quot;/g,'"')
        .replace(/&#039;/g,"'");
}

答案 13 :(得分:0)

function htmlEscape(str){
    return str.replace(/[&<>'"]/g,x=>'&#'+x.charCodeAt(0)+';')
}

此解决方案使用字符的数字代码,例如<替换为&#60;

尽管其性能略逊于the solution using a map,但它具有以下优点:

  • 不依赖于库或DOM
  • 非常容易记住(您不需要记住5个HTML转义字符)
  • 小代码
  • 相当快(它仍然比5链替换快)

答案 14 :(得分:0)

我正在详细说明o.k.w.的答案。

您可以为此使用浏览器的DOM功能。

var utils = {
    dummy: document.createElement('div'),
    escapeHTML: function(s) {
        this.dummy.textContent = s
        return this.dummy.innerHTML
    }
}

utils.escapeHTML('<escapeThis>&')

这将返回&lt;escapeThis&gt;&amp;

它使用标准函数createElement创建一个不可见元素,然后使用函数textContent将任何字符串设置为其内容,然后使用innerHTML以其HTML表示形式获取内容

答案 15 :(得分:0)

这与这个问题没有直接关系,但是相反的情况可以通过以下方式在JS中完成:

> String.fromCharCode(8212);
> "—"

这也适用于TypeScript。