Nginx 就像一个专业的“门口保安”。不仅能决定谁能进来(反向代理),还能在后端服务把“包裹”(HTTP 响应)递给访客之前,对包裹进行最后的检查和“包装”。有时候,后端服务(比如 PHP)递出来的包裹上会贴一些不该贴的标签,或者贴错了标签,它就可以把这些标签撕掉、换掉或者贴上新标签。
一、为什么要修改后端返回的 Header?
修改 Header 的主要原因有三个:
- 安全!安全!安全!
- 后端应用经常会“不经意地”在 Header 里暴露自己的版本信息,比如
X-Powered-By: PHP/7.4.3或Server: Apache/2.4.41。这就像告诉小偷你家门锁的型号,非常不安全。我们必须隐藏它!
- 后端应用经常会“不经意地”在 Header 里暴露自己的版本信息,比如
- 修正或统一
- 后端程序员可能设置了一个错误的
Cache-Control策略,导致资源无法被浏览器缓存。我们可以在 Nginx 层快速修正,而无需重新部署后端代码。 - 多个后端服务返回的 Header 可能格式不一,我们可以在 Nginx 层进行统一,提供一致的客户端体验。
- 后端程序员可能设置了一个错误的
- 添加缺失的 Header
- 后端可能忘记添加一些重要的安全 Header,比如
X-Frame-Options(防止点击劫持) 或Content-Security-Policy。Nginx 可以统一为所有响应添加这些“安全补丁”。
- 后端可能忘记添加一些重要的安全 Header,比如
二、核心“三板斧”指令
Nginx 标准模块提供了两把有力的武器,通常组合使用。
| 指令 | 说明 | 注意事项 |
|---|---|---|
add_header | 添加一个 Header | 如果后端已经返回了同名 Header, add_header不会覆盖,而是会再添加一个,导致出现重复的 Header。 |
proxy_hide_header | 隐藏来自后端的指定 Header | 它只负责“藏”,不负责修改或添。 |
既然 add_header 是添加重复的,而 proxy_hide_header 是隐藏,那我们如何实现“覆盖”呢? 答案很简单:先藏,再加! proxy_hide_header + add_header 组合拳,天下我有!
三、配置示例
下面是几个常见场景的“标准操作”,可以直接复制使用。
场景一:隐藏敏感信息(必备安全操作)
目标:隐藏后端返回的 X-Powered-By 和 Server 头。
location / {
# 告诉 Nginx,从后端拿到的响应里,把这两个 Header 藏起来
proxy_hide_header X-Powered-By;
proxy_hide_header Server;
# ... 其他配置,例如 ...
proxy_pass http://your_backend_server;
}
提示:Nginx 自己也会默认添加一个 Server: nginx 的 Header。如果你想彻底隐藏,需要在 http 配置块中设置 server_tokens off;。
场景二:覆盖后端的 Cache-Control Header
目标:无论后端返回什么样的 Cache-Control,我们都强制覆盖为 public, max-age=3600。
location /static/ {
# 第1步:先把后端可能返回的 Cache-Control 头藏起来
proxy_hide_header Cache-Control;
# 第2步:添加我们自己的 Cache-Control 头
# 使用 "always" 参数可以确保即使是错误页面(如404)也能加上这个头
add_header Cache-Control "public, max-age=3600" always;
# ... 其他配置 ...
proxy_pass http://your_backend_server;
}
这个“先藏再加”的组合是 Nginx 修改后端 Header 的精髓所在。
场景三:添加后端忘记加的 X-Frame-Options
目标:为所有页面添加 X-Frame-Options 头,防止网站被嵌入到 <iframe> 中。
server {
# ... server 配置 ...
# 直接添加即可,因为后端很可能没有这个头
add_header X-Frame-Options "SAMEORIGIN" always;
location / {
# ... location 配置 ...
proxy_pass http://your_backend_server;
}
}
最后,别忘了修改配置后检查并重新加载 Nginx:
sudo nginx -t
sudo nginx -s reload