HTML模板比字符串拼接更适合依赖注入,因为HTML是嵌套状态机结构,正则或replace()会错判注释、CDATA、自闭合标签(如<img src="<script>">),导致注入偏移、属性截断或XSS;只有parse5、BeautifulSoup等浏览器级解析器才能准确识别<head>和<body>节点并安全插入。
因为 HTML 是嵌套状态机结构,正则或 replace() 会错判注释、CDATA、自闭合标签(比如 <img src="<script>">),导致注入位置偏移、属性截断,甚至引入 XSS。只有用 parse5、BeautifulSoup 这类浏览器级解析器,才能准确识别 <head> 和 <body> 节点并安全插入。
运行时用 fetch() 加载 navbar.html 看似简单,实际会触发三类问题:
<body> 已开始渲染innerHTML = data 在严格策略下直接报 Refused to set unsafe HTML
构建时用 vite-plugin-html 或 html-webpack-plugin + html-webpack-template 内联片段,输出纯静态 HTML,无延迟、无 CSP 冲突、无 SEO 风险。
<template> 本身不能直接实现依赖注入<template> 只提供“不渲染的 DOM 片段”,它不支持传参、条件判断或自动引用外部资源。单独写个 <template id="card"><div>{{title}}</div></template> 不会自动替换 {{title}} —— 你得配合 JavaScript 手动克隆、填充、插入,比如用 document.importNode(template.content, true)。
立即学习“前端免费学习笔记(深入)”;
真正起作用的是组合用法:
<slot> 做内容占位,配合 Web Components 封装逻辑<template> 当成“藏 HTML 的 div”来用,否则和硬编码没区别用浏览器里的 DOMParser 处理用户提交的 HTML 并不可靠:它不保留 <!DOCTYPE html>,可能把 UTF-8 编码转成 UTF-16,还无法剥离恶意脚本——用户提交的 <script>alert(1)</script> 会在解析前就执行。
服务端解析器(如 parse5)能先做节点清洗、转义危险内容,再注入可信资源,最后用 parse5.serialize() 输出合法 HTML,确保 DOCTYPE、charset、命名空间全部 intact。
复杂点在于 SRI(Subresource Integrity):CDN 资源若启用了 integrity 校验,注入 <script src="..."> 时必须同步计算哈希并写入 integrity 属性,否则在启用 require-sri-for script style 的 CSP 下直接被拦截。