有人尝试在js中重新创建smarty:
// actually from a template file, not hardcoded in the javascript
html = '<span class="{test}">yay</span>';
html = change(html, 'test', 'foo bar');
function change(html, key, value){
html = html.replace('{'+key+'}',value);
html = html.replace('%7B'+key+'%7D',value);
return html;
}
element.innerHTML = html;
在FF中这很好(正如预期的那样):
<span class="foo bar">yay</span>
在IE 7/8中,可能是6 ...它给了我这个:
<span class="foo" bar="">yay</span>
为什么它会创建额外属性而不是按照我的预期去做?
答案 0 :(得分:3)
有人尝试在js中重新创建smarty
我真的希望他们不会这样做......!
我怀疑这里发生的是代码是从元素的innerHTML
抓取原始HTML而不是上面写的字符串。在这种情况下,IE会将其DOM序列化为它认为格式化HTML标记的好方法,这可能与它最初提供的标记不太相似。在这种情况下它可能做的一个值得怀疑的事情是省略引号:
<SPAN class={test}>yay</SPAN>
“但是,这不是有效的HTML!”,你抱怨道。 Pfft - 就像IE一样关心。
现在进行替换,你得到:
<SPAN class=foo bar>yay</SPAN>
bar
显然是一个新属性,当您将其写回innerHTML
时将被解析为单独的Attr节点。
再一次,道德是不用正则表达式处理HTML。当您阅读innerHTML
时,浏览器不再需要为您提供正确的HTML,而不是普通的不熟练的HTML author-clod。
此代码不仅会因此情况而失败,还会导致密钥中的正则表达式特殊字符或值中的替换特殊字符或任何地方的HTML特殊字符,并且不允许相同的密钥两次,并且一些未知的原因试图模拟URL编码的字符串(?),如果替换值包含大括号,可能会搞乱。
如果您可以将其全部保存在DOM中,则分配给span.className
既简单又安全。如果你必须使用HTML字符串模板(如果你这样做,你需要查看HTML转义以避免困扰大多数JS模板系统的漏洞XSS漏洞),那么你需要将输入HTML模板保持为原始文本字符串,而不是从DOM中读取它。