我正在构建一个Web应用程序(使用原型),该应用程序需要在DOM中添加大块HTML。其中大多数是包含具有各种属性方式的元素的行。
目前,我在变量中保留HTML的空白行,
var blankRow = '<tr><td>' +'<a href="{LINK}" onclick="someFunc(\'{STRING}\');">{WORD}</a>' +'</td></tr>'; function insertRow(o) { newRow = blankRow .sub('{LINK}',o.link) .sub('{STRING}',o.string) .sub('{WORD}',o.word); $('tbodyElem').insert( newRow ); }
现在一切正常,花花公子,但这是最佳做法吗?
当我更新页面上的代码时,我必须更新blankRow中的代码,因此要插入的新元素相同。当我有40行HTML放入blankRow中时,它变得很烂,然后我也必须对其进行转义。
有更容易的方法吗?我当时考虑过urlencoding,然后在插入之前对其进行解码,但这仍然意味着blankRow和很多转义。
这将意味着PHP等人的eof函数。
$blankRow = <<<EOF text text EOF;
那将意味着没有逃避,但仍然需要一个blankRow。
在这种情况下您会做什么?
最终在原型中使用DOMBuilder。不需要其他库:
$w('a div p span img table thead td th tr tbody tfoot input').each(function(e) { window['$' + e] = function() { return new Element(e, arguments[0]); } }); newPart = $div({id: 'partition-4'}) .insert( $p() .insert('<b>Stuff</b>') ) .insert( $p({ id: 'a-p'}) .insert('<b>More stuff</b>') ); $('parentDiv').insert(newPart);
在这里或这里查看我的解决方案。
这是最佳做法吗?
不会。实际上,您有HTML注入问题导致错误,在最坏的情况下,注入的字符串可能包含用户提交的内容,因此XSS安全漏洞。
将纯文本内容和属性值放入HTML字符串时, 必须对其进行 HTML编码。在PHP中,您必须调用htmlspecialchars()进入HTML的字符串来执行此操作。在JavaScript中,您没有内置的HTML转义功能,因此您必须自己编写。通过使用s.replace(/&/g, '&').replace(/</g, '<').replace(/"/g, '"')进入HTML的字符串。
htmlspecialchars()
s.replace(/&/g, '&').replace(/</g, '<').replace(/"/g, '"')
onclick =“ someFunc('{STRING} ');”
这是逃避混乱的全新境界。在事件处理程序属性内的JavaScript字符串文字中,您必须对字符串进行JS编码(\-escaping '以及\一些Unicode字符以确保完整性) , 然后对结果进行HTML编码。否则,字符串可以突破其字符串字面定界符,并注入任意JS代码。在所有情况下都应避免使用内联事件处理程序属性,尤其是在模板中。
\
'
用HTML字符串创建页面内容很糟糕。您很可能会产生转义错误并损害应用程序的安全性。改用类似DOM的方法,您不必为此担心。您似乎正在使用jQuery,因此请尝试使用jQuery 1.4元素创建快捷方式:
$('<tr>').append( $('<td>').append( $('<a>', { href: o.link, text: o.word, onclick: function() { someFunc(o.string); } }) ) );
或者,将空白行实际上保留为HTML文档,然后将其隐藏(display: none)或在启动时将其与文档分离(removeChild或jQuery detach)。然后,当需要新行时,克隆空白行并进行所需的更改:
display: none
removeChild
detach
var blankRow= $('#blankRow').detach(); ... var newRow= blankRow.clone(); var link= newRow.find('td>a'); link.attr('href': o.link); link.text(o.word); link.click(function() { someFunc(o.string); });
如果必须从字符串模板创建内容,请确保默认情况下模板函数HTML会转义每个替换,并通过选择要解析的内容内的节点来附加事件click(function() { ... })。或者使用事件委托(例如jQuery live())来处理事件,而不必在添加时绑定到新节点。
click(function() { ... })
live()