<input id='hiddenId' type='hidden' value='chalk & cheese' />
通过某些jQuery将
放入
<input type='text' value='chalk & cheese' />
从jQuery中获取值隐藏字段(这是我现在丢失的编码):
$('#hiddenId').attr('value')
问题是当我从隐藏字段中读取
chalk & cheese
时,JavaScript似乎丢失了编码。我不希望该值是chalk & cheese
。我希望保留原义amp;
。是否有JavaScript库或jQuery方法可以对字符串进行HTML编码?
#1 楼
编辑:此答案发布很久以前,并且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
。在此处检查运行示例。
评论
这适用于大多数情况,但是htmlDecode的此实现将消除任何多余的空格。因此,对于“输入”的某些值,请输入!= htmlDecode(htmlEncode(input))。在某些情况下,这对我们来说是个问题。例如,如果输入=“
\ t Hi \ n There
”,则往返编码/解码将产生“Hi There
”。在大多数情况下,这是可以的,但有时不是。 :)–小资
2010-3-19在16:25
感谢您的解决方案!我解决了消除多余的空白问题,方法是在文本值中用%% NL %%替换新行,然后调用.html()以获取HTML编码值,然后用
替换%% NL %% s ...不是防弹符号,但是可以用,我的用户不太可能输入%% NL %%。
– Benno
2011年8月4日10:59
该解决方案可能取决于页面是用html还是xhtml编写的,因此我希望使用不涉及DOM的解决方案。
– Phil H
2012年6月18日11:00
尽管两年后得到了答复,但下面的@Anentropic的回复在各个方面都更好。
–乍得
2012年7月19日,下午4:51
似乎不适用于编码“,我尝试了$('')。text('“')。html();但这只是给我“。
– andrewb
2013年12月22日下午4:55
#2 楼
jQuery技巧不对引号进行编码,在IE中,它将删除空格。基于Django中的转义templatetag,我猜它已经被大量使用/测试了,我做了此函数
它比空白消除问题的任何变通办法都更简单(并且可能更快)-并且它对引号进行了编码,这对于在内部使用结果时必不可少的例如属性值。
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:
在寻找最快的转义过程中,我发现了
replaceAll
方法的这种实现:http://dumpsite.com/forum/index.php?topic = 4.msg29#msg29 (在此也引用:替换字符串中字符的所有实例的最快方法)
某些性能结果在这里:http://jsperf.com/htmlencoderegex/25
它为上面的内置
replace
链提供了相同的结果字符串。 更新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, '/');
评论
没有/g,.replace()将仅替换第一个匹配项。
–ThinkingStiff
13年6月15日在3:36
@ Tracker1我不同意,如果该函数收到无效的输入,则应该引发错误。如果在特定的用例中,您想以这种方式处理无效的输入,则可以在调用函数之前检查该值,或者将该函数调用包装在try / catch中。
–熵
16年7月14日在9:27
#3 楼
这是一个非jQuery版本,比jQuery.html()
版本和.replace()
版本都快得多。这样会保留所有空格,但像jQuery版本一样,不会处理引号。 function htmlEncode( html ) {
return document.createElement( 'a' ).appendChild(
document.createTextNode( html ) ).parentNode.innerHTML;
};
速度:http://jsperf.com/htmlencoderegex/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 = '<div> & hello</div>';
document.getElementById( 'same' ).textContent =
'html === htmlDecode( htmlEncode( html ) ): '
+ ( html === htmlDecode( htmlEncode( html ) ) );
HTML:
<input id="hidden" type="hidden" value="chalk & cheese" />
<input id="text" value="" />
<div id="same"></div>
评论
这引出了一个问题:为什么它已经不是JS中的全局函数了?
– SEoF
2013年6月14日上午10:58
@SEoF最近建议的非正则表达式.replace()版本要快得多:jsperf.com/htmlencoderegex/22
–熵
2013年6月14日22:30在
@Anentropic的确确实发光很快,但是我认为它没有用。如果没有/g,.replace()只会进行第一个匹配。
–ThinkingStiff
13年6月15日在3:38
有趣的是,在Firefox中,您可以执行replace('a','b','g'),其功能与replace(/ a / g,'b')相同...尽管速度也相同
–熵
2013年6月17日14:26
我都不是:)我开始只是想处理引号,而我最终还是追求速度...
–熵
2013年6月17日15:02
#4 楼
我知道这是一个旧的,但是我想发布一个已接受的答案的变体,该变体将在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();
}
#5 楼
下划线提供了执行此操作的_.escape()
和_.unescape()
方法。> _.unescape( "chalk & cheese" );
"chalk & cheese"
> _.escape( "chalk & cheese" );
"chalk & cheese"
评论
Lodash也有类似的方法。
–古斯塔沃·斯特劳伯(Gustavo Straube)
17-10-16在13:05
#6 楼
好答案。请注意,如果使用jQuery 1.4.2进行编码的值是undefined
或null
,则可能会出现以下错误:jQuery("<div/>").text(value).html is not a function
或
Uncaught TypeError: Object has no method 'html'
解决方案是修改功能以检查实际值:
function htmlEncode(value){
if (value) {
return jQuery('<div/>').text(value).html();
} else {
return '';
}
}
评论
jQuery('')。text(value ||'').html()
–常规
2011年9月6日在22:59
@roufamatic-不错的一线。但是使用if检查非空值可以省去在运行时创建DIV并获取其值的麻烦。如果经常调用htmlEncode,并且值很可能为空,则可以提高性能。
–力宝
2011年9月9日19:49
嗨,它不对&beta做β知道为什么吗?
– Dilip Rajkumar
13年7月24日在8:55
#7 楼
对于那些喜欢纯JavaScript的人,这是我成功使用的方法:function escapeHTML (str)
{
var div = document.createElement('div');
var text = document.createTextNode(str);
div.appendChild(text);
return div.innerHTML;
}
#8 楼
FWIW,编码不会丢失。页面加载期间,标记解析器(浏览器)使用该编码。一旦读取并解析了源并将浏览器将DOM加载到内存中,就将编码解析为它所表示的内容。因此,当您的JS执行执行以读取内存中的任何内容时,它得到的字符就是编码所表示的内容。我可能在这里严格地根据语义进行操作,但是我希望您了解编码。 “丢失”一词听起来好像有些东西无法正常运行。
#9 楼
没有Jquery时速度更快。您可以对字符串中的每个字符进行编码:function encode(e){return e.replace(/[^]/g,function(e){return"&#"+e.charCodeAt(0)+";"})}
,或者只针对主要字符担心(&,inebreaks,<,>,“和'),例如:
function encode(r){
return r.replace(/[\x26\x0A\<>'"]/g,function(r){return"&#"+r.charCodeAt(0)+";"})
}
test.value=encode('Encode HTML entities!\n\n"Safe" escape <script id=\'\'> & useful in <pre> tags!');
testing.innerHTML=test.value;
/*************
* \x26 is &ersand (it has to be first),
* \x0A is newline,
*************/
<textarea id=test rows="9" cols="55"></textarea>
<div id="testing">www.WHAK.com</div>
#10 楼
原型具有内置的String类。因此,如果您正在使用/计划使用原型,它会执行以下操作:'<div class="article">This is an article</div>'.escapeHTML();
// -> "<div class="article">This is an article</div>"
评论
它也不应该用引号做些什么吗?这不好
–熵
2011年8月19日在13:49
@Anentropic我不明白为什么它需要对引号做任何事情;因为引号不需要转义,除非它们位于属性值之内。
–安迪
13年6月28日在8:04
好了,经过一番思考之后,我回想一下该评论-如果您要构建一段HTML,则希望对其中的每个部分(包括属性值)进行编码,因此我同意Anentropic,并且我认为Prototypejs函数不足这种情况。
–安迪
13年6月28日在8:49
#11 楼
这是一个简单的javascript解决方案。它使用方法“ HTMLEncode”扩展了String对象,该方法可以在不带参数或带有参数的对象上使用。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("æåøåæå"))
我的要旨是“ HTMLEncode方法” javascript”。
#12 楼
基于angular的清理...(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, '<');
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};
评论
虽然我确实很喜欢这个答案,但实际上我认为这是一个好方法,但是我怀疑if(value === null | value === undefined)return''的按位运算符是;错字或实际上是功能?如果是这样,为什么要使用那个而不是普通的||? ?谢谢!!
–亚历杭德罗·瓦尔斯(Alejandro Vales)
17-10-17在13:02
@AlejandroVales我很确定这是一个错字...已更正。
–Tracker1
17-10-19在23:02
好吧,请记住,将导致0或1,所以实际上它确实起作用了^^
–亚历杭德罗·瓦尔斯(Alejandro Vales)
17-10-20在6:41
您不能只使用== null吗? undefined是唯一与null等效的东西,因此无论如何都不需要两个三等式
–棕褐色
18-10-16在6:32
那根本不是真的。 null和0都是虚假的,是的,所以您不能只做!value,但是==的要点是使某些事情变得容易。 0 == null为假。未定义== null为true。你可以做值== null
–棕褐色
18-10-18在0:26
#13 楼
据我所知,javascript中没有任何直接的HTML Encode / Decode方法。但是,您可以做的是使用JS创建任意元素,设置其内部文本,然后使用innerHTML阅读。
比方说,使用jQuery,这应该可以工作:
var helper = $('chalk & cheese').hide().appendTo('body');
var htmled = helper.html();
helper.remove();
或者类似的方法。
评论
考虑到这个答案几乎与拥有870多个赞成票并且在此之后发表了一点意见的答案几乎相同,我觉得这种投票有点有趣。
– Ken Egozi
16-2-3在21:56
#14 楼
您不必转义/编码值即可将它们从一个输入字段穿梭到另一个输入域。<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.write
或eval
之类的奇怪操作,否则HTML编码将有效地透明。如果您要生成一个新的文本框来保存结果,那么它仍然一样容易。只需将HTML的静态部分传递给jQuery,然后在它返回给您的对象上设置其余的属性/属性。
$box = $('<input type="text" name="whatever">').val($('#hiddenId').val());
#15 楼
我遇到了类似的问题,并使用JavaScript(文档)中的功能encodeURIComponent
进行了解决。例如,如果您使用的是:<input id='hiddenId' type='hidden' value='chalk & cheese' />
和
encodeURIComponent($('#hiddenId').attr('value'))
您将得到
chalk%20%26%20cheese
。即使保留空格也是如此。在我的情况下,我必须对一个反斜杠进行编码,并且此代码可以完美运行
encodeURIComponent('name/surname')
,我得到了
name%2Fsurname
#16 楼
以下是一些用纯JavaScript编写的来自Microsoft ASP的Server.HTMLEncode
函数的模仿: 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范围以外的任何字符。
#17 楼
我的纯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实体编码和解码
#18 楼
如果要使用jQuery。我发现了这一点:http://www.jquerysdk.com/api/jQuery.html特殊字符
(jQuery SDK提供的jquery.string插件的一部分)
我相信Prototype的问题在于它扩展了JavaScript中的基础对象,并且将与您可能使用的任何jQuery不兼容。当然,如果您已经在使用Prototype而不是jQuery,那将不会有问题。
编辑:也有这个,这是Prototype的jQuery字符串实用程序的一部分:
http://stilldesigning.com/dotstring/
#19 楼
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源代码。
#20 楼
<script>
String.prototype.htmlEncode = function () {
return String(this)
.replace(/&/g, '&')
.replace(/"/g, '"')
.replace(/'/g, ''')
.replace(/</g, '<')
.replace(/>/g, '>');
}
var aString = '<script>alert("I hack your site")</script>';
console.log(aString.htmlEncode());
</script>
输出:
<script>alert("I hack your site")</script>
.htmlEncode()一旦定义就可以在所有字符串上访问。
#21 楼
HTML编码给定值 var htmlEncodeContainer = $('<div />');
function htmlEncode(value) {
if (value) {
return htmlEncodeContainer.text(value).html();
} else {
return '';
}
}
#22 楼
我在Domain \ User字符串中遇到了反斜杠的一些问题。我将此添加到Anentropic的答案的其他转义中
.replace(/\/g, '\')
我在这里找到了:
如何在JavaScript中转义反斜杠?
#23 楼
在prototype.js中选择escapeHTML()
的功能添加此脚本可以帮助您逃脱HTML:
String.prototype.escapeHTML = function() {
return this.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>')
}
现在您可以在字符串上调用escapeHTML方法了在您的脚本中,例如:
var escapedString = "<h1>this is HTML</h1>".escapeHTML();
// gives: "<h1>this is HTML</h1>"
希望它可以帮助寻找简单解决方案的任何人,而不必包括整个prototype.js
#24 楼
使用此处的其他一些答案,我制作了一个版本,该版本一次通过替换了所有相关字符,而不考虑不同编码字符的数量(仅一次调用replace()
),因此对于较大的字符串会更快。它不依赖于DOM API的存在或其他库。
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); }; })();
pre >
已经运行了一次,现在可以调用
encodeHTML('<>&"\'')
获取<>&"'
#25 楼
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, "\nenc: " + enc, "\ndec: " + dec);
评论
可以显示您正在使用的Javascript吗?添加了我如何从隐藏字段中获取价值的方法
不要使用innerHTML方法(jQuery .html()方法使用innerHTML),因为在某些(我刚刚测试过Chrome的)浏览器中,这不会转义引号,因此,如果要将值放入属性值,最终将导致XSS漏洞。
粉笔和奶酪在什么情况下一起使用过0_o
比较两个项目时,@ d -_- b。例。它们和粉笔和奶酪一样;)