必须在HTML中配置Content-Security-Policy以防范XSS,且<meta charset="UTF-8">须置于<head>最前以避免乱码和解析错乱;CSP不可仅依赖<meta>,X-Content-Type-Options和X-Frame-Options等安全头必须由服务器返回。

Content-Security-Policy 必须配,否则 <script> 和 <img> 标签加载来源失控,XSS 风险直接上升。
为什么 meta charset="UTF-8" 要放在最前面
浏览器解析 HTML 时,一旦遇到非 ASCII 字符(比如中文、emoji),而此时还没读到 <meta charset="UTF-8">,就会按默认编码(通常是 ISO-8859-1)尝试解码,结果出现乱码或截断;更严重的是,某些旧版 IE 甚至会触发两次重排,导致脚本执行错乱。
-
<meta charset="UTF-8">必须是<head>中第一个有效标签(<title>前也行,但不能在注释或空格之后) - 不要写成
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">—— HTML5 已废弃该写法,部分构建工具(如 Vite)会忽略它 - 若用 Webpack 或 Rollup 构建,确认模板 HTML 文件里没被插件自动删掉这行
Content-Security-Policy 的最小可用配置
不设 CSP 等于把脚本执行权交给所有第三方域名;只设 default-src 'self' 又太严,连内联 <script> 和 style 都会失败。
- 基础起步:
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' 'unsafe-inline' https:; style-src 'self' 'unsafe-inline'"> -
'unsafe-inline'是过渡期妥协,上线后应逐步替换成nonce或hash(例如script-src 'self' 'sha256-xxx...') - 禁止
eval()和new Function():加上script-src 'self' 'unsafe-inline' 'unsafe-eval'就等于开后门,务必删掉'unsafe-eval' - 如果用了 Google Analytics 或 Sentry,得显式加域名:
script-src 'self' www.googletagmanager.com cdn.sentry.io
X-Content-Type-Options 和 X-Frame-Options 不能靠 <meta> 实现
<meta> 标签无法设置 HTTP 响应头,这两个安全头必须由服务器返回。前端硬塞 <meta http-equiv="X-Content-Type-Options" content="nosniff"> 完全无效,浏览器直接忽略。
立即学习“前端免费学习笔记(深入)”;
-
X-Content-Type-Options: nosniff防止 MIME 类型嗅探,避免.txt被当成text/html执行 JS -
X-Frame-Options: DENY或SAMEORIGIN阻止点击劫持,DENY更安全(除非你明确需要嵌入 iframe) - Nginx 配置示例:
add_header X-Content-Type-Options "nosniff" always;;Apache 用Header set指令 - 现代项目建议用
Content-Security-Policy: frame-ancestors 'none'替代X-Frame-Options,兼容性更好且支持更多策略
真正起效的安全头几乎都不靠 HTML 标签,而是服务器响应头;<meta> 能做的只有 CSP(部分浏览器支持)和字符集声明。别在 <head> 里堆一堆无效的 http-equiv,那只是自我安慰。



















