我使用JavaScript从隐藏字段中拉出一个值并在文本框中显示它。隐藏字段中的值被编码。

例如,

<input id='hiddenId' type='hidden' value='chalk &amp; cheese' />

被卷入

<input type='text' value='chalk &amp; cheese' />

通过一些jQuery来获取隐藏字段的值(在这一点上,我失去了编码):

$('#hiddenId').attr('value')

问题是当我读粉笔&cheese从隐藏字段,JavaScript似乎失去了编码。我不希望价值是粉笔和奶酪。我想要字面上的amp;被保留。

是否有JavaScript库或jQuery方法可以对字符串进行html编码?


当前回答

基于angular的sanitize…(es6模块语法)

// ref: https://github.com/angular/angular.js/blob/v1.3.14/src/ngSanitize/sanitize.js
const SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
const NON_ALPHANUMERIC_REGEXP = /([^\#-~| |!])/g;

const decodeElem = document.createElement('pre');


/**
 * Decodes html encoded text, so that the actual string may
 * be used.
 * @param value
 * @returns {string} decoded text
 */
export function decode(value) {
  if (!value) return '';
  decodeElem.innerHTML = value.replace(/</g, '&lt;');
  return decodeElem.textContent;
}


/**
 * Encodes all potentially dangerous characters, so that the
 * resulting string can be safely inserted into attribute or
 * element text.
 * @param value
 * @returns {string} encoded text
 */
export function encode(value) {
  if (value === null || value === undefined) return '';
  return String(value).
    replace(/&/g, '&amp;').
    replace(SURROGATE_PAIR_REGEXP, value => {
      var hi = value.charCodeAt(0);
      var low = value.charCodeAt(1);
      return '&#' + (((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000) + ';';
    }).
    replace(NON_ALPHANUMERIC_REGEXP, value => {
      return '&#' + value.charCodeAt(0) + ';';
    }).
    replace(/</g, '&lt;').
    replace(/>/g, '&gt;');
}

export default {encode,decode};

其他回答

function encodeHTML(str) { return document.createElement(“a”).appendChild( document.createTextNode(str)).parentNode.innerHTML; }; 函数解码HTML(str) { var element = document.createElement(“a”); element.innerHTML = str; 返回元素文本内容; }; var str = “<” var enc = encodeHTML(str); var dec = decodeHTML(enc); console.log(“str: ” + str, “\nenc: ” + enc, “\ndec: ” + dec);

jQuery的技巧不编码引号,在IE中它会删除你的空白。

基于Django中的escape templatetag,我猜它已经被大量使用/测试过了,我做了这个函数来做需要的事情。

可以说,它比解决空格剥离问题的任何变通方法都更简单(而且可能更快)——而且它对引号进行了编码,例如,如果您打算在属性值中使用结果,那么引号是必不可少的。

function htmlEscape(str) {
    return str
        .replace(/&/g, '&amp;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#39;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;');
}

// I needed the opposite function today, so adding here too:
function htmlUnescape(str){
    return str
        .replace(/&quot;/g, '"')
        .replace(/&#39;/g, "'")
        .replace(/&lt;/g, '<')
        .replace(/&gt;/g, '>')
        .replace(/&amp;/g, '&');
}

更新2013-06-17: 在寻找最快的转义,我发现了一个replaceAll方法的实现: http://dumpsite.com/forum/index.php?topic=4.msg29#msg29 (这里也引用了:替换字符串中所有字符实例的最快方法) 下面是一些性能结果: http://jsperf.com/htmlencoderegex/25

它给出了与上面的内置替换链相同的结果字符串。如果有人能解释为什么它更快,我会很高兴!?

更新2015-03-04: 我刚刚注意到AngularJS正在使用上面的方法: https://github.com/angular/angular.js/blob/v1.3.14/src/ngSanitize/sanitize.js#L435

他们增加了一些改进——他们似乎在处理一个模糊的Unicode问题,以及将所有非字母数字字符转换为实体。在我的印象中,后者是不需要的,只要您为您的文档指定了UTF8字符集。

我要指出的是,(4年后)Django仍然没有做这些事情,所以我不确定它们有多重要: https://github.com/django/django/blob/1.8b1/django/utils/html.py#L44

更新2016-04-06: 你也可能希望转义正斜杠/。对于正确的HTML编码,这不是必需的,但是OWASP建议将其作为一种抗xss安全措施。(感谢@JNF在评论中提出这个建议)

        .replace(/\//g, '&#x2F;');

这是一个模拟服务器的程序。HTMLEncode函数来自微软的ASP,用纯JavaScript编写:

htmlEncode函数{ var ntable = { “l”:“amp,” “50%”:“莉莉。托姆琳”, “>”:“gt”, “\“”:“参与的。” 出于美观; s=s.replace(/[&<>")/ g, function (ch){ 返回"&"+ntable[ch]+";"; 出于美观) s = s.replace(/[胡言乱语])/g, function(ch) 返回"&#"+ch.charcodeat(0).tostring()+";"; 出于美观); s return; 出于美观

结果不编码撇号,而是编码其他HTML特殊字符和0x20-0x7e范围之外的任何字符。

如果你想使用jQuery。我发现了这个:

http://www.jquerysdk.com/api/jQuery.htmlspecialchars

(jquery的一部分。jQuery SDK提供的字符串插件

我认为Prototype的问题在于它扩展了JavaScript中的基本对象,并且与你可能使用过的任何jQuery都不兼容。当然,如果你已经在使用Prototype而不是jQuery,这就不是问题。

编辑:还有这个,这是Prototype的字符串实用工具的jQuery端口:

http://stilldesigning.com/dotstring/

好的答案。注意,在jQuery 1.4.2中,如果要编码的值是undefined或null,你可能会得到如下错误:

jQuery("<div/>").text(value).html不是一个函数

OR

对象没有方法“html”

解决方案是修改函数来检查实际值:

function htmlEncode(value){ 
    if (value) {
        return jQuery('<div/>').text(value).html(); 
    } else {
        return '';
    }
}