每个示例都设置相同的初始值。托管平台可能已经发送 Strict-Transport-Security,因此 Vercel、Netlify 和 Next.js 示例中没有包含它;请检查实际响应,只在缺少时添加。
nginx
把这些行放在提供 HTTPS 的 server 块中。always 参数会让它们也出现在错误响应中。带有自己 add_header 行的 location 块会丢弃从 server 块继承的所有 add_header,所以要在那里重复整组设置,或把它们放在一个 include 文件中。
# In the server block that serves HTTPS (listen 443 ssl)
add_header Strict-Transport-Security "max-age=300" always;
add_header Content-Security-Policy-Report-Only "default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
Apache
启用 mod_headers,并把这些行添加到 443 端口的虚拟主机中,或添加到已设置 AllowOverride FileInfo 的 .htaccess 中。Header always set 同样适用于错误响应和重定向。
# <VirtualHost *:443> or .htaccess; needs mod_headers (Debian/Ubuntu: a2enmod headers)
Header always set Strict-Transport-Security "max-age=300"
Header always set Content-Security-Policy-Report-Only "default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'"
Header always set X-Frame-Options "SAMEORIGIN"
Header always set X-Content-Type-Options "nosniff"
Header always set Referrer-Policy "strict-origin-when-cross-origin"
Header always set Permissions-Policy "camera=(), microphone=(), geolocation=()"
Cloudflare
在控制台中为你的主机名创建一条 Response Header Transform Rule,并用 Set static 操作添加每个响应头;该操作会替换源站发送的同名响应头。HSTS 在 SSL/TLS 的 Edge Certificates 下有单独的设置;二者只用其一。菜单名称可能因控制台版本而不同。
Rule type Response Header Transform Rule
When Hostname equals example.com
Then Set static, one row per header:
X-Content-Type-Options nosniff
Referrer-Policy strict-origin-when-cross-origin
X-Frame-Options SAMEORIGIN
Permissions-Policy camera=(), microphone=(), geolocation=()
Content-Security-Policy-Report-Only default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'
HSTS SSL/TLS > Edge Certificates > HTTP Strict Transport Security (HSTS)
Vercel
在项目根目录的 vercel.json 中添加 headers 条目。source 模式 /(.*) 匹配所有路径;如果某些路由需要不同的策略,请缩小范围。
{
"headers": [
{
"source": "/(.*)",
"headers": [
{ "key": "Content-Security-Policy-Report-Only", "value": "default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'" },
{ "key": "X-Frame-Options", "value": "SAMEORIGIN" },
{ "key": "X-Content-Type-Options", "value": "nosniff" },
{ "key": "Referrer-Policy", "value": "strict-origin-when-cross-origin" },
{ "key": "Permissions-Policy", "value": "camera=(), microphone=(), geolocation=()" }
]
}
]
}
Netlify
在发布目录(即 Netlify 部署的文件夹)中创建名为 _headers 的文件。每个路径行(如 /*)后面跟着缩进的“名称: 值”行。同样的规则也可以写在 netlify.toml 的 [[headers]] 下。
/*
Content-Security-Policy-Report-Only: default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()
Next.js
在 next.config.js 的 async headers() 函数中返回这些响应头;source '/:path*' 覆盖所有路由。静态导出(output: 'export')时 headers() 不会运行,此时请在提供导出文件的主机上设置响应头。
// next.config.js
const securityHeaders = [
{ key: 'Content-Security-Policy-Report-Only', value: "default-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'self'" },
{ key: 'X-Frame-Options', value: 'SAMEORIGIN' },
{ key: 'X-Content-Type-Options', value: 'nosniff' },
{ key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
{ key: 'Permissions-Policy', value: 'camera=(), microphone=(), geolocation=()' },
];
module.exports = {
async headers() {
return [{ source: '/:path*', headers: securityHeaders }];
},
};
部署后再次运行此工具:它读取最终响应,因此会显示 CDN 或平台实际发送的内容。然后在浏览器开发者工具中打开一个错误页面和一个静态文件,因为响应头经常只为部分响应设置。