我使用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。

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

其他回答

没有Jquery更快。你可以对字符串中的每个字符进行编码:

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

或者只关注主要角色(&,inebreaks, <, >, "和'),比如:

函数编码(r) { 返回r.replace (/ [\ x26 \ x0A \ < > "] / g函数(r){返回" & # + r.charCodeAt(0) +”;“}) } 测试。value=encode('编码HTML实体!\n\n"安全"转义<脚本id=\'\'> &有用在<pre>标签!'); testing.innerHTML = test.value; /************* * \x26是& &号(必须排在第一位), * \x0A为换行符, *************/ <textarea id=test rows="9" cols="55"></textarea> www.WHAK.com < div id = "测试" > < / div >

编辑:这个答案是很久以前发布的,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。

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

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;');

您不应该为了将值从一个输入字段转移到另一个输入字段而对值进行转义/编码。

<form>
 <input id="button" type="button" value="Click me">
 <input type="hidden" id="hiddenId" name="hiddenId" value="I like cheese">
 <input type="text" id="output" name="output">
</form>
<script>
    $(document).ready(function(e) {
        $('#button').click(function(e) {
            $('#output').val($('#hiddenId').val());
        });
    });
</script>

JS不会插入原始HTML或其他东西;它只是告诉DOM设置value属性(或属性;不确定)。无论哪种方式,DOM都可以为您处理任何编码问题。除非你在做一些奇怪的事情,比如使用document。写或eval, html编码将是有效透明的。

如果你正在讨论生成一个新的文本框来保存结果……还是那么简单。只需要将HTML的静态部分传递给jQuery,然后设置它返回给你的对象的其余属性/属性。

$box = $('<input type="text" name="whatever">').val($('#hiddenId').val());

我的pure-JS函数:

/**
 * HTML entities encode
 *
 * @param {string} str Input text
 * @return {string} Filtered text
 */
function htmlencode (str){

  var div = document.createElement('div');
  div.appendChild(document.createTextNode(str));
  return div.innerHTML;
}

JavaScript HTML实体编码和解码