Javascript 从输入字段读取属性时HTML编码丢失

Javascript 从输入字段读取属性时HTML编码丢失,javascript,jquery,html,escaping,html-escape-characters,Javascript,Jquery,Html,Escaping,Html Escape Characters,我正在使用JavaScript从隐藏字段中提取一个值,并将其显示在文本框中。隐藏字段中的值已编码 比如说, 卷入 通过一些jQuery从隐藏字段中获取值(此时我丢失了编码): $('hiddenId').attr('value')) 问题是当我读粉笔时;cheese从隐藏字段中,JavaScript似乎丢失了编码。我不希望值为粉笔和奶酪。我想要文字amp将被保留 是否有JavaScript库或jQuery方法可以对字符串进行HTML编码?据我所知,JavaScript中没有任何直接的H

我正在使用JavaScript从隐藏字段中提取一个值,并将其显示在文本框中。隐藏字段中的值已编码

比如说,


卷入


通过一些jQuery从隐藏字段中获取值(此时我丢失了编码):

$('hiddenId').attr('value'))
问题是当我读粉笔时;cheese从隐藏字段中,JavaScript似乎丢失了编码。我不希望值为
粉笔和奶酪
。我想要文字
amp将被保留


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

据我所知,JavaScript中没有任何直接的HTML编码/解码方法

但是,您可以使用JS创建任意元素,设置其内部文本,然后使用innerHTML读取它

比方说,使用jQuery,这应该可以:

var helper = $('chalk & cheese').hide().appendTo('body');
var htmled = helper.html();
helper.remove();
或者类似的东西。

有内置的。因此,如果您正在使用/计划使用Prototype,它会执行以下操作:

'<div class="article">This is an article</div>'.escapeHTML();
// -> "&lt;div class="article"&gt;This is an article&lt;/div&gt;"
“这是一篇文章”。escapeHTML();
//->“div class=“article”这是一篇文章/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();
}
函数htmlEncode(值){
//创建内存元素,设置其内部文本(自动编码)
//然后把编码后的内容取出来。DOM中不存在该元素。
返回$('').text(value.html();
}
函数htmlDecode(值){
返回$('').html(value.text();
}
基本上,textarea元素是在内存中创建的,但它从未附加到文档中

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


检查一个正在运行的示例。

FWIW,编码没有丢失。在页面加载期间,标记解析器(浏览器)使用该编码。一旦读取并解析了源代码,浏览器将DOM加载到内存中,编码就被解析为它所表示的内容。因此,当执行JS读取内存中的任何内容时,它得到的字符就是编码所表示的字符


我可能在这里严格地操作语义,但我想让您理解编码的目的。“丢失”这个词听起来好像有些东西不能正常工作。

我知道这是一个旧的,但我想发布一个变体,它可以在IE中工作,而不删除行:

函数MultileHTMLENCODE(值){
var line=value.split(/\r\n |\r |\n/);
对于(变量i=0;i
回答得好。请注意,如果jQuery 1.4.2中要编码的值为
undefined
null
,则可能会出现以下错误:

jQuery(“”).text(value).html不是函数

未捕获类型错误:对象没有方法“html”

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

function htmlEncode(value){ 
    if (value) {
        return jQuery('<div/>').text(value).html(); 
    } else {
        return '';
    }
}
函数htmlEncode(值){
如果(值){
返回jQuery(“”).text(value).html();
}否则{
返回“”;
}
}

jQuery技巧不会对引号进行编码,在IE中,它会去除您的空白

基于Django中的escapetemplatetag,我猜它已经被大量使用/测试过了,我制作了这个函数,它完成了所需的功能

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

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, '&');
}

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

<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>

这是一个非jQuery版本,它比jQuery
.html()
版本和
.replace()
版本都要快得多。这将保留所有空格,但与jQuery版本一样,不处理引号

函数htmlEncode(html){
return document.createElement('a')。appendChild(
document.createTextNode(html)).parentNode.innerHTML;
};
速度:

演示:

输出:

脚本:
函数htmlEncode(html){
return document.createElement('a')。appendChild(
document.createTextNode(html)).parentNode.innerHTML;
};
函数htmlDecode(html){
var a=document.createElement('a');a.innerHTML=html;
返回a.textContent;
};
document.getElementById('text').value=htmlEncode(document.getElementById('hidden').value);
//健康检查
var html='&;你好;
document.getElementById('same')。textContent=
'html==htmlDecode(htmlEncode(html)):'
+(html==htmlDecode(htmlEncode(html));
HTML:
如果要使用jQuery。我发现:

(jquery SDK提供的jquery.string插件的一部分)

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

编辑:还有这个,它是Prototype用于jQuery的字符串实用程序的一个端口:

<
<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>
$box = $('<input type="text" name="whatever">').val($('#hiddenId').val());
function escapeHTML (str)
{
    var div = document.createElement('div');
    var text = document.createTextNode(str);
    div.appendChild(text);
    return div.innerHTML;
}
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
    };
})();
> _.unescape( "chalk &amp; cheese" );
  "chalk & cheese"

> _.escape( "chalk & cheese" );
  "chalk &amp; cheese"
<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>
String.prototype.HTMLEncode = function(str) {
  var result = "";
  var str = (arguments.length===1) ? str : this;
  for(var i=0; i<str.length; i++) {
     var chrcode = str.charCodeAt(i);
     result+=(chrcode>128) ? "&#"+chrcode+";" : str.substr(i,1)
   }
   return result;
}
// TEST
console.log("stetaewteaw æø".HTMLEncode());
console.log("stetaewteaw æø".HTMLEncode("æåøåæå"))
function encode(e){return e.replace(/[^]/g,function(e){return"&#"+e.charCodeAt(0)+";"})}
  var htmlEncodeContainer = $('<div />');
  function htmlEncode(value) {
    if (value) {
      return htmlEncodeContainer.text(value).html();
    } else {
      return '';
    }
  }
// 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};
.replace(/\\/g, '&#92;')
<input id='hiddenId' type='hidden' value='chalk & cheese' />
encodeURIComponent($('#hiddenId').attr('value'))
encodeURIComponent('name/surname')
String.prototype.escapeHTML = function() { 
    return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;')
}
var escapedString = "<h1>this is HTML</h1>".escapeHTML();
// gives: "&lt;h1&gt;this is HTML&lt;/h1&gt;"
/**
 * 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;
}