按场景组织的即用型配置片段,复制后改域名和路径即可。
二级目录映射到后端服务
前后端分离后常见「前端一个端口、后端一个端口」。要在同一个域名同一个端口下同时提供两者,用反向代理把 /api/ 转发到后端:
location ^~ /api/ {
proxy_pass https://example.com:4433/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
^~表示以/api/开头匹配,不能用~(正则匹配时proxy_pass不能再带 URI);proxy_pass结尾的/必须写,否则/api/index.php会被代理成/api/index.php而非后端根路径。
反向代理完整参数
location / {
proxy_pass http://example.com;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_max_temp_file_size 0;
proxy_connect_timeout 90;
proxy_send_timeout 90;
proxy_read_timeout 90;
proxy_buffer_size 4k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
proxy_temp_file_write_size 64k;
}
HTTP 强制跳转 HTTPS
server {
listen 80 default_server;
server_name example.com;
rewrite ^(.*) https://$server_name$1 permanent;
# 也可以写成
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name example.com;
}
HSTS 保持 HTTPS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
max-age:强制使用 HTTPS 的时长(秒),这里为 1 年;includeSubDomains:所有子域同时生效;preload:非规范值,用于申请加入 HSTS 预加载列表;always:保证所有响应(含内置错误页)都带上该头。
非标准 HTTPS 端口重定向
让 2083 这类非标准端口也支持 HTTP 跳 HTTPS:
error_page 497 https://$host:2083$request_uri;
否则用户用 HTTP 访问 HTTPS 端口会报 The plain HTTP request was sent to HTTPS port。
端口转发(暴露内网服务)
把内网 192.168.1.2:3306 通过本机的 33062 端口暴露出去:
upstream TCP3306 {
hash $remote_addr consistent;
server 192.168.1.2:3306;
}
server {
listen 33062;
proxy_connect_timeout 5s;
proxy_timeout 300s;
proxy_pass TCP3306;
}
跨域
if ($request_method = OPTIONS ) {
add_header "Access-Control-Allow-Origin" *;
add_header "Access-Control-Allow-Methods" "GET, POST, OPTIONS, HEAD";
add_header "Access-Control-Allow-Headers" "Authorization, Origin, X-Requested-With, Content-Type, Accept";
add_header 'Access-Control-Max-Age' 600;
return 200;
}
带 cookie 的跨域,需要指定具体源并开启 credentials:
server {
listen 81;
server_name www.domain1.com;
location / {
proxy_pass http://www.domain2.com:8080;
proxy_cookie_domain www.domain2.com www.domain1.com; # 修改 cookie 里的域名
index index.html index.htm;
# 前端只跨域不带 cookie 时,Allow-Origin 可为 *
add_header Access-Control-Allow-Origin http://www.domain1.com;
add_header Access-Control-Allow-Credentials true;
}
}
用
webpack-dev-server等中间件代理接口时没有浏览器参与,不受同源限制,上面这段可不加。
跨域传递 Cookie
Chrome 80+ 默认禁止第三方 Cookie,除非服务端显式设置 SameSite:
| 取值 | 行为 |
|---|---|
Strict | 完全禁止第三方 Cookie,跨站任何情况都不发送 |
Lax | 大多数情况不发送,但导航到目标网址的 GET 请求除外 |
None | 允许跨站发送,但必须同时设置 Secure(仅 HTTPS) |
Set-Cookie: widget_session=abc123; SameSite=None; Secure
另一种思路是 proxy_pass 反向代理:仅转换 Host 和端口时 Cookie 不会丢失;路径变化时需要额外做 Cookie 路径转换。
Gzip 压缩
http {
gzip on;
gzip_types text/plain application/javascript text/css application/xml text/javascript image/jpeg image/gif image/png;
gzip_comp_level 5;
gzip_vary on;
gzip_buffers 16 8k;
gzip_disable "MSIE [1-6]\."; # 低版本 IE 不支持压缩
gzip_http_version 1.1;
gzip_min_length 2k;
gzip_proxied off;
}
| 参数 | 释义 |
|---|---|
gzip | 开关 |
gzip_types | 按文件类型选择性压缩 |
gzip_comp_level | 压缩级别,越高越耗时、压缩率越好 |
gzip_vary | 是否在响应头加 Vary: Accept-Encoding |
gzip_buffers | 压缩请求缓冲区数量与大小 |
gzip_disable | 针对特定 UA 关闭压缩 |
gzip_http_version | 触发压缩的最低 HTTP 版本 |
gzip_min_length | 触发压缩的最小文件大小 |
gzip_proxied | 是否压缩后端响应结果 |
- 图片、视频类型默认已开启压缩,一般无需重复配置;
.js要写成application/javascript,不是text/javascript或application/x-javascript。
动静分离
location ~ .*\.(html|htm|gif|jpg|jpeg|bmp|png|ico|txt|js|css)$ {
root /data/www/static;
expires 30d;
}
静态资源直接由 Nginx 返回,动态请求才转发给后端,可显著降低后端压力。
代理缓存
http {
# 缓存目录:内存缓存区 hot_cache 128m,3 天未访问自动清除,磁盘上限 2GB
proxy_cache_path /log/nginx/cache levels=1:2 keys_zone=hot_cache:128m inactive=3d max_size=2g;
server {
location / {
proxy_cache hot_cache;
proxy_cache_valid 200 206 304 301 302 1d;
proxy_cache_valid any 30m;
proxy_cache_key $host$uri$is_args$args;
proxy_cache_min_uses 3; # 至少访问 3 次才加入缓存
proxy_cache_lock on; # 回源时只放行一个请求
proxy_cache_lock_timeout 3s;
proxy_no_cache $cookie_nocache $arg_nocache $arg_comment;
add_header Cache-status $upstream_cache_status; # 便于调试命中情况
}
}
}
proxy_cache_path 关键参数:
| 参数 | 含义 |
|---|---|
path | 缓存路径 |
levels | 目录层次结构,最多三层 |
keys_zone | 共享内存空间(1M 约存 8000 个 Key) |
inactive | 多久未被访问后删除,默认十分钟 |
max_size | 最大存储空间,超出后按 LRU 移除 |
use_temp_path | 是否使用临时目录 |
IP 黑白名单
单个 IP 直接写在 location 里:
server {
location ^~ /my_api/ {
deny 192.177.12.222; # 屏蔽单个 IP
deny 127.0.0.0/8; # 屏蔽网段
allow 192.177.44.201; # 允许单个 IP
allow 127.45.0.0/16; # 允许网段
deny all; # 其余全部禁止
}
}
只允许内网访问管理后台:
location /admin {
allow 192.168.1.0/24;
allow 10.0.0.0/24;
deny all;
}
规则自上而下匹配,命中即停止。批量 IP 建议抽成 .conf 文件后用 include 引入。
防盗链
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {
valid_referers none blocked *.example.com example.com;
if ($invalid_referer) {
return 403;
}
}
大文件传输优化
client_max_body_size 100m;
client_body_buffer_size 1m;
proxy_request_buffering off; # 大文件上传时边收边转发
proxy_read_timeout 300s;
过滤请求方法
明确只用 GET / POST / HEAD 时,其他方法直接屏蔽:
if ($request_method !~ ^(GET|HEAD|POST)$) {
return 404;
}
超时设置
http {
client_body_timeout 10;
client_header_timeout 30;
keepalive_timeout 30 30;
send_timeout 10;
}
隐藏版本号
避免版本漏洞被猜解:
server_tokens off;