HTML-encoding lost when attribute read from input field
我正在使用JavaScript从隐藏字段中提取值并将其显示在文本框中。 隐藏字段中的值已编码。
例如,
1 | <input id='hiddenId' type='hidden' value='chalk & cheese' /> |
被拉进去
1 | <input type='text' value='chalk & cheese' /> |
通过一些jQuery从隐藏字段中获取值(此时我丢失了编码):
1 | $('#hiddenId').attr('value') |
问题是,当我从隐藏字段中读取
是否有一个JavaScript库或jQuery方法将对字符串进行HTML编码?
编辑:这个答案很久以前发布了,
我使用这些功能:
1 2 3 4 5 6 7 8 9 | 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(); } |
基本上,div元素在内存中创建,但它永远不会附加到文档中。
在
在这里查看一个运行示例。
jQuery技巧不对引号进行编码,在IE中它会剥离你的空白。
基于Django中的转义模板标签,我猜我已经大量使用/测试了,我做了这个功能,它可以满足需要。
它可以说比空白剥离问题的任何变通方法更简单(也可能更快) - 并且它编码引号,如果您要在属性值中使用结果,这是必不可少的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | function htmlEscape(str) { return str .replace(/&/g, '&') .replace(/"/g, '"') .replace(/'/g, ''') .replace(/</g, '<') .replace(/>/g, '>'); } // I needed the opposite function today, so adding here too: function htmlUnescape(str){ return str .replace(/"/g, '"') .replace(/'/g,"'") .replace(/</g, '<') .replace(/>/g, '>') .replace(/&/g, '&'); } |
更新2013-06-17:
在寻找最快的转义时,我发现了
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:
您可能还希望逃避正斜杠
1 | .replace(/\//g, '/'); |
这是一个非jQuery版本,比jQuery
1 2 3 4 | function htmlEncode( html ) { return document.createElement( 'a' ).appendChild( document.createTextNode( html ) ).parentNode.innerHTML; }; |
速度:http://jsperf.com/htmlencoderegex/17
演示: sub> sub> sub>
输出:
脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | function htmlEncode( html ) { return document.createElement( 'a' ).appendChild( document.createTextNode( html ) ).parentNode.innerHTML; }; function htmlDecode( html ) { var a = document.createElement( 'a' ); a.innerHTML = html; return a.textContent; }; document.getElementById( 'text' ).value = htmlEncode( document.getElementById( 'hidden' ).value ); //sanity check var html = ' & hello'; document.getElementById( 'same' ).textContent = 'html === htmlDecode( htmlEncode( html ) ): ' + ( html === htmlDecode( htmlEncode( html ) ) ); |
HTML:
1 2 | <input id="hidden" type="hidden" value="chalk & cheese" /> <input id="text" value="" /> |
我知道这是一个旧的,但我想发布一个接受的答案的变体,将在IE中工作而不删除行:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | function multiLineHtmlEncode(value) { var lines = value.split(/ | | /); for (var i = 0; i < lines.length; i++) { lines[i] = htmlEncode(lines[i]); } return lines.join(' '); } function htmlEncode(value) { return $('').text(value).html(); } |
Underscore提供了执行此操作的
1 2 3 4 5 | > _.unescape("chalk & cheese" ); "chalk & cheese" > _.escape("chalk & cheese" ); "chalk & cheese" |
好答案。请注意,如果要使用jQuery 1.4.2编码的值为
要么
解决方案是修改函数以检查实际值:
1 2 3 4 5 6 7 | function htmlEncode(value){ if (value) { return jQuery('').text(value).html(); } else { return ''; } } |
对于那些喜欢普通javascript的人来说,这是我成功使用的方法:
1 2 3 4 5 6 7 | function escapeHTML (str) { var div = document.createElement('div'); var text = document.createTextNode(str); div.appendChild(text); return div.innerHTML; } |
FWIW,编码不会丢失。在页面加载期间,标记解析器(浏览器)使用编码。一旦读取并解析了源并且浏览器将DOM加载到内存中,编码就会被解析为它所代表的内容。因此,当您的JS执行以读取内存中的任何内容时,它获取的char就是编码所代表的内容。
我可能在这里严格操作语义,但我希望你理解编码的目的。"迷失"这个词听起来似乎有些东西不像它应该的那样工作。
没有Jquery更快。您可以对字符串中的每个字符进行编码:
1 | function encode(e){return e.replace(/[^]/g,function(e){return"&#"+e.charCodeAt(0)+";"})} |
或者只是针对主角担心(&amp;,inebreaks,<,>,"和'),如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | function encode(r){ return r.replace(/[\x26\x0A\<>'"]/g,function(r){return"&#"+r.charCodeAt(0)+";"}) } test.value=encode('Encode HTML entities! "Safe" escape <script id=\'\'> & useful in [cc lang="javascript"] tags!'); testing.innerHTML=test.value; /************* * \x26 is &ersand (it has to be first), * \x0A is newline, *************/ |
1 2 3 | <textarea id=test rows="9" cols="55"></textarea> www.WHAK.com |
Prototype内置了String类。因此,如果您正在使用/计划使用Prototype,它会执行以下操作:
1 2 | 'This is an article'.escapeHTML(); // ->"<div class="article">This is an article</div>" |
这是一个简单的JavaScript解决方案。它使用方法"HTMLEncode"扩展String对象,该方法可用于没有参数的对象或参数。
1 2 3 4 5 6 7 8 9 10 11 12 | 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("??????")) |
我已经为"javascript的HTMLEncode方法"做了一个主旨。
基于angular的sanitize ...(es6模块语法)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | // 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, '<'); 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, '&'). 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, '<'). replace(/>/g, '>'); } export default {encode,decode}; |
我有一个类似的问题,并使用JavaScript中的函数
例如,在您的情况下,如果您使用:
1 | <input id='hiddenId' type='hidden' value='chalk & cheese' /> |
和
1 | encodeURIComponent($('#hiddenId').attr('value')) |
你会得到
在我的情况下,我不得不编码一个反斜杠,这段代码完美无缺
1 | encodeURIComponent('name/surname') |
我得到了
您不必转义/编码值,以便将它们从一个输入字段移动到另一个输入字段。
1 2 3 4 5 6 7 8 9 10 11 | <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> $(document).ready(function(e) { $('#button').click(function(e) { $('#output').val($('#hiddenId').val()); }); }); |
JS不会插入原始HTML或任何东西;它只是告诉DOM设置
如果你正在谈论生成一个新的文本框来保存结果......它仍然很容易。只需将HTML的静态部分传递给jQuery,然后在它返回给您的对象上设置其余的属性/属性。
1 | $box = $('<input type="text" name="whatever">').val($('#hiddenId').val()); |
afaik在javascript中没有任何直接的HTML Encode / Decode方法。
但是,你可以做的是使用JS创建一个任意元素,设置它的内部文本,然后使用innerHTML读取它。
说,使用jQuery这应该工作:
1 2 3 | var helper = $('chalk & cheese').hide().appendTo('body'); var htmled = helper.html(); helper.remove(); |
或者沿着这些方向的东西
我的纯JS功能:
1 2 3 4 5 6 7 8 9 10 11 12 | /** * 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 Entities Encode & Decode
如果你想使用jQuery。我找到了这个:
http://www.jquerysdk.com/api/jQuery.htmlspecialchars
(jQuery SDK提供的jquery.string插件的一部分)
我相信Prototype的问题在于它扩展了JavaScript中的基础对象,并且与您可能使用的任何jQuery不兼容。当然,如果你已经在使用Prototype而不是jQuery,那就不会有问题了。
编辑:还有这个,它是Prototype的jQuery字符串实用程序的一个端口:
http://stilldesigning.com/dotstring/
1 2 3 4 5 6 7 8 9 10 11 12 | String.prototype.htmlEncode = function () { return String(this) .replace(/&/g, '&') .replace(/"/g, '"') .replace(/'/g, ''') .replace(/</g, '<') .replace(/>/g, '>'); } var aString = 'alert("I hack your site")'; console.log(aString.htmlEncode()); |
将输出:
一旦定义,所有字符串都可以访问.htmlEncode()。
HtmlEncodes给定的值
1 2 3 4 5 6 7 8 | var htmlEncodeContainer = $(''); function htmlEncode(value) { if (value) { return htmlEncodeContainer.text(value).html(); } else { return ''; } } |
我在Domain User字符串中遇到了反斜杠的一些问题。
我把这个添加到Anentropic答案的其他逃脱中
1 | .replace(/\\/g, '\') |
我在这里找到的:
如何在JavaScript中逃避反斜杠?
这里有一点模仿Microsoft的ASP中的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | function htmlEncode(s) { var ntable = { "&":"amp", "<":"lt", ">":"gt", """:"quot" }; s = s.replace(/[&<>"]/g, function(ch) { return"&" + ntable[ch] +";"; }) s = s.replace(/[^ -\x7e]/g, function(ch) { return"&#" + ch.charCodeAt(0).toString() +";"; }); return s; } |
结果不会对撇号进行编码,而是对其他HTML特殊内容以及0x20-0x7e范围之外的任何字符进行编码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | var htmlEnDeCode = (function() { var charToEntityRegex, entityToCharRegex, charToEntity, entityToChar; function resetCharacterEntities() { charToEntity = {}; entityToChar = {}; // add the default set addCharacterEntities({ '&' : '&', '>' : '>', '<' : '<', '"' : '"', ''' : "'" }); } 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的源代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | function encodeHTML(str) { return document.createElement("a").appendChild( document.createTextNode(str)).parentNode.innerHTML; }; function decodeHTML(str) { var element = document.createElement("a"); element.innerHTML = str; return element.textContent; }; var str ="<" var enc = encodeHTML(str); var dec = decodeHTML(enc); console.log("str:" + str," enc:" + enc," dec:" + dec); |
选择
添加此脚本可帮助您转义HTML:
1 2 3 | String.prototype.escapeHTML = function() { return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>') } |
现在你可以在脚本中的字符串上调用escapeHTML方法,例如:
1 2 | var escapedString ="this is HTML".escapeHTML(); // gives:"<h1>this is HTML</h1>" |
希望它能帮助任何寻找简单解决方案的人,而不必包含整个prototype.js
在这里使用其他一些答案,我创建了一个版本,可以替换一次传递中的所有相关字符,而不管不同编码字符的数量(只有一次调用
它不依赖于DOM API存在或其他库。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | window.encodeHTML = (function() { function escapeRegex(s) { return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); } var encodings = { '&' : '&', '"' : '"', '\'' : ''', '<' : '<', '>' : '>', '\' : '/' }; function encode(what) { return encodings[what]; }; var specialChars = new RegExp('[' + escapeRegex(Object.keys(encodings).join('')) + ']', 'g'); return function(text) { return text.replace(specialChars, encode); }; })(); |
跑了一次,你现在可以打电话了
1 | encodeHTML('<>&"\'') |
获得