我使用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编码?


当前回答

编辑:这个答案是很久以前发布的,htmlDecode函数引入了一个XSS漏洞。它已被修改,将临时元素从div改为textarea,减少XSS的机会。但是现在,我鼓励您像其他回答中建议的那样使用DOMParser API。


我使用这些函数:

function htmlEncode(value){
  // Create a in-memory element, set its inner text (which is automatically encoded)
  // Then grab the encoded contents back out. The element never exists on the DOM.
  return $('<textarea/>').text(value).html();
}

function htmlDecode(value){
  return $('<textarea/>').html(value).text();
}

基本上,textarea元素是在内存中创建的,但它永远不会追加到文档中。

在htmlEncode函数上,我设置了元素的innerText,并检索编码的innerHTML;在htmlDecode函数上,我设置了元素的innerHTML值,并检索了innerText。

在这里查看一个正在运行的示例。

其他回答

我知道这是一个老问题,但我想发布一个可接受的答案的变化,在IE中工作而不删除行:

function multiLineHtmlEncode(value) {
    var lines = value.split(/\r\n|\r|\n/);
    for (var i = 0; i < lines.length; i++) {
        lines[i] = htmlEncode(lines[i]);
    }
    return lines.join('\r\n');
}

function htmlEncode(value) {
    return $('<div/>').text(value).html();
} 
<script>
String.prototype.htmlEncode = function () {
    return String(this)
        .replace(/&/g, '&amp;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#39;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;');

}

var aString = '<script>alert("I hack your site")</script>';
console.log(aString.htmlEncode());
</script>

将输出:&lt;script&gt;alert(&quot;I hack your site&quot;)&lt;/script&gt;

. htmlencode()一旦定义,就可以在所有字符串上访问。

我有一个类似的问题,解决它使用函数encodeURIComponent从JavaScript(文档)

例如,在你的例子中,如果你使用:

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

and

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

你会得到粉笔%20%26%20奶酪。甚至空格也要保留。

在我的情况下,我必须编码一个反斜杠,这段代码完美地工作

encodeURIComponent('name/surname')

我的名字是% 2姓氏

Prototype内置了String类。所以如果你正在使用/计划使用Prototype,它会像这样做:

'<div class="article">This is an article</div>'.escapeHTML();
// -> "&lt;div class="article"&gt;This is an article&lt;/div&gt;"
var htmlEnDeCode = (function() {
    var charToEntityRegex,
        entityToCharRegex,
        charToEntity,
        entityToChar;

    function resetCharacterEntities() {
        charToEntity = {};
        entityToChar = {};
        // add the default set
        addCharacterEntities({
            '&amp;'     :   '&',
            '&gt;'      :   '>',
            '&lt;'      :   '<',
            '&quot;'    :   '"',
            '&#39;'     :   "'"
        });
    }

    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的源代码。