我有这个JS代码,它在tbody
中添加了一些HTML:
thestring='<tr><td><input type="text" name="entry-'+s+'-api" value="'+getItem('entry-'+s+'-api')+' /></td><td><input type="text" name="entry-'+s+'-talk" value="'+getItem('entry-'+s+'-talk')+' /></td><td><input type="text" name="entry-'+s+'-url" value="'+getItem('entry-'+s+'-url')+' /></td></tr>';
document.getElementById('table').innerHTML+=thestring;
有点长队,我知道...
因此,当我运行它时,thestring
被正确评估为:
<input type="text" name="entry-0-api" value="http%3A%2F%2Flego.wikia.com%2Fapi.php /><<input type="text" name="entry-0-talk" value="User_talk%3AUltrasonicNXT /><input type="text" name="entry-0-url" value="http%3A%2F%2Flego.wikia.com%2Fwiki%2FUser_talk%3AUltrasonicNXT />
但是,这是添加的内容:
<tr><td></td></tr>
那么其余的都去哪儿了呢?
这是相关的 HTML:
<form action="change.js" method="GET">
<table>
<tbody id="table">
</tbody>
</table>
</form>
value="'+getItem('entry-'+s+'-api')+' />
标记不正确。属性值没有结束引号。Chrome正在尽最大努力清理错误。
但是,无论如何,您都不应该以这种方式构建标记字符串。如果getItem
值中有任何 HTML 特殊字符,则它们将能够泄漏到标记中。如果任何内容来自不受信任的第三方,则此HTML注入不仅是错误,而且是安全漏洞。
document.getElementById('table').innerHTML+=thestring;
永远不要这样做。这会将表的整个当前 DOM 转换为 HTML 标记,添加到该字符串中,并将其全部解析回新对象,替换旧对象。这很慢,并且会丢失任何未序列化为 HTML 的信息(例如事件处理程序或表单字段值)。
直接更改文档的实时 DOM 节点比弄乱 HTML 标记要可靠得多。这解决了这两个问题。例如:
var row= document.getElementById('table').insertRow(-1);
['api', 'talk', 'url'].forEach(function(prop) {
var name= 'entry-'+s+'-'+prop;
var input= document.createElement('input');
input.type= 'text';
input.name= name;
input.value= getItem(name);
row.insertCell(-1).appendChild(input);
});
<input type="text" name="entry-0-api" value="http%3A%2F%2Flego.wikia.com%2Fapi.php /><
不正确。 您缺少<tr><td>
(症状或疏忽),但您还有一个未关闭的value
属性(似乎是原因)和一个额外的<
(这又看起来像症状,因为它不一致)。 格式不正确的数据会导致一些问题。