提供一段文本
<b>This is some text</b>
我希望将其写入我的页面,以便它显示为:
<b>这是一些文本</b>
而不是像这样
这是一些文本
使用escape("<b>这是一些文本</b>")
在Firefox中会得到以下结果:
%3Cb%3EThis%20is%20some%20text%3C/b%3E
不完全是我想要的。有什么想法吗?
提供一段文本
<b>This is some text</b>
我希望将其写入我的页面,以便它显示为:
<b>这是一些文本</b>
而不是像这样
这是一些文本
使用escape("<b>这是一些文本</b>")
在Firefox中会得到以下结果:
%3Cb%3EThis%20is%20some%20text%3C/b%3E
不完全是我想要的。有什么想法吗?
这应该对你有用:http://blog.nickburwell.com/2011/02/escape-html-tags-in-javascript.html
function escapeHTML( string )
{
var pre = document.createElement('pre');
var text = document.createTextNode( string );
pre.appendChild(text);
return pre.innerHTML;
}
安全警告
该函数未对单引号和双引号进行转义,如果在错误的上下文中使用,仍可能导致XSS攻击。例如:
var userWebsite = '" onmouseover="alert(\'gotcha\')" "';
var profileLink = '<a href="' + escapeHtml(userWebsite) + '">Bob</a>';
var div = document.getElemenetById('target');
div.innerHtml = profileLink;
// <a href="" onmouseover="alert('gotcha')" "">Bob</a>
针对 HTML DOM 文档可用的情况,我喜欢 @limc 的回答。
对于非 HTML DOM 文档环境(如 Node.js),我喜欢 @Michele Bosi 和 @Paolo 的回答。
@Michael Bosi 的答案可以通过移除 4 次调用 replace 并使用聪明的替换函数来进行优化:
function escape(s) {
let lookup = {
'&': "&",
'"': """,
'\'': "'",
'<': "<",
'>': ">"
};
return s.replace( /[&"'<>]/g, c => lookup[c] );
}
console.log(escape("<b>This is 'some' text.</b>"));
使用精心选择的正则表达式可以优化Paolo的范围测试,并且可以通过使用替换函数来消除for循环:
@Paolo的范围测试可以通过精心选择的正则表达式进行优化,使用替换函数可以消除for循环:
function escape(s) {
return s.replace(
/[^0-9A-Za-z ]/g,
c => "&#" + c.charCodeAt(0) + ";"
);
}
console.log(escape("<b>This is 'some' text</b>"));
正如 @Paolo 所指出的,这种策略将适用于更多的情况。
'
),因为在 HTML 中它可以用来代替引号包装属性值。你可以用 '
替换它。 - Finesse我最终做了这个:
function escapeHTML(s) {
return s.replace(/&/g, '&')
.replace(/"/g, '"')
.replace(/</g, '<')
.replace(/>/g, '>');
}
'
),因为它在 HTML 中可以代替引号。你可以用 '
替换它。 - Finessefunction htmlEntities(str) {
return String(str).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
}
如果你使用的是XHTML,你需要使用CDATA
部分。在HTML中也可以使用这些,但HTML不太严格。
我将字符串常量分开,以便此代码可以内联在CDATA块中的XHTML上运行。如果您将JavaScript作为单独的文件源,请不必担心。请注意,如果您正在使用带有内联JavaScript的XHTML,则需要将代码包含在CDATA块中,否则其中一些内容将无法正常工作。您会遇到奇怪、微妙的错误。
function htmlentities(text) {
var escaped = text.replace(/\]\]>/g, ']]' + '>]]><' + '![CDATA[');
return '<' + '![CDATA[' + escaped + ']]' + '>';
}
转义文本的“正确”方式是使用DOM函数document.createTextNode
。这并不实际转义文本;它只是告诉浏览器创建一个文本元素,该元素本质上是未解析的。然而,您必须愿意使用DOM才能使此方法起作用:也就是说,您必须使用appendChild
等方法,而不是innerHTML
属性或类似的方法。这将填充具有ID an-element
的元素,并且该文本将不被解析为(X)HTML:
var textNode = document.createTextNode("<strong>This won't be bold. The tags " +
"will be visible.</strong>");
document.getElementById('an-element').appendChild(textNode);
jQuery提供了一个方便的DOM封装器text
,代替了JavaScript中的createTextNode
。这非常方便。以下是使用jQuery实现相同功能的示例:
$('#an-element').text("<strong>This won't be bold. The tags will be " +
"visible.</strong>");
function htmlEntities( html ) {
html = html.replace( /[<>]/g, function( match ) {
if( match === '<' ) return '<';
else return '>';
});
return html;
}
console.log( htmlEntities( '<b>replaced</b>' ) ); // <b>replaced</b>
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>
function Escape( s )
{
var h,
i,
n,
c;
n = s.length;
h = '';
for( i = 0; i < n; i++ )
{
c = s.charCodeAt( i );
if( ( c >= 48 && c <= 57 )
||( c >= 65 && c <= 90 )
||( c >= 97 && c <=122 )
||( c == 32 ) )
{
h += String.fromCharCode( c );
}
else
{
h += '&#' + c + ';';
}
}
return h;
}
例子:
Escape('<b>This is some text</b>')
返回
<b>这是一些文本</b>
该函数能够防止代码注入攻击,支持Unicode,纯JavaScript。
虽然这种方法比创建DOM文本节点的方法慢约50倍,但该函数仍然可以在100-150毫秒内转义一百万(1,000,000)个字符的字符串。
(在2011年早期的MacBook Pro上测试- Safari 9 - Mavericks)