# 通用配置
# 定义HTTPS服务器块
server {
# 监听443端口,启用SSL
listen 443 ssl;
# 指定服务器域名
server_name xyz.xianyu.com;
# SSL证书文件路径
ssl_certificate /usr/local/nginx/ssl/xyz.xianyu.com/xyz.xianyu.com.pem;
# SSL证书私钥文件路径
ssl_certificate_key /usr/local/nginx/ssl/xyz.xianyu.com/xyz.xianyu.com.key;
# SSL会话超时时间设置为5分钟
ssl_session_timeout 5m;
# 启用的SSL协议版本(TLSv1.2和TLSv1.3)
ssl_protocols TLSv1.2 TLSv1.3;
# 允许的SSL加密套件
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
# 优先使用服务器端的加密套件
ssl_prefer_server_ciphers on;
# 匹配根路径的所有请求
location / {
# 设置网站根目录
root /web/build/bill;
# 设置默认首页文件
index index.html;
# 尝试匹配文件:先找具体文件,再找目录,都找不到则返回index.html
try_files $uri $uri/ /index.html;
}
# 匹配以/prod-api开头的API请求
location /prod-api/ {
# 反向代理到后端服务
proxy_pass http://127.0.0.1:19001/;
# 传递原始Host头信息
proxy_set_header Host $host;
# 传递客户端真实IP地址
proxy_set_header X-Real-IP $remote_addr;
# 传递客户端IP链(包含代理信息)
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 设置请求开始时间戳
proxy_set_header X-Request-Start $msec;
}
}
# 定义HTTP服务器块(用于重定向到HTTPS)
server {
# 监听80端口(HTTP默认端口)
listen 80;
# 匹配相同的域名
server_name bill.xianyu.info;
# 301永久重定向到HTTPS版本的相同URL
# $host - 域名
# $request_uri - 完整的请求URI(包含查询参数)
return 301 https://$host$request_uri;
}
# 关键参数解析
# location
根据URI匹配不同的处理规则
# 精确匹配 (=)
location = /api/login {}
只匹配/api/login,不匹配其他,包括/api/login/ /api/login/xyz
# 优先前缀匹配 (^~)
location ^~ /images {}
匹配以 /images开头的URI,路径级别的匹配,不是简单的字符串前缀
会匹配:
/images/images//images/logo.png/images/icons/home.svg/images/gallery/
不会匹配:
/images1/images-test/myimages/images123/test.jpg
匹配到后立即结束
# 正则匹配 (~ 区分大小写, ~* 不区分大小写)
location ~ \.(jpg|jpeg|png|gif)$
location ~* /API/
匹配到后立即结束,不再匹配其他正则
# 前缀匹配
location /api {}
匹配所有以/api开头的URI
会匹配
/api/api//api/login/apilogin/api1/api2/api/1234
location /api/ {}
匹配所有以/api/开头的URI
会匹配
/api//api/1/api/2/api/login
不会匹配
/api/api1
如果存在多个前缀匹配,则匹配最长的那个
# proxy_pass
proxy_pass 分为2种规则:不带URI和带URI
- 不带URI:只包含IP和端口号,比如
https://www.xianyu.info - 带URI:端口后带其他路径的,比如
https://www.xianyu.info/https://www.xianyu.info/apihttps://www.xianyu.info/api/login
以请求地址
/api/login为例请求转发到
http://127.0.0.1:8080
# 不带URI
核心,一句话:保留整个请求路径,拼接到代理服务器地址后
location /api {
proxy_pass http://localhost:8080;
}
保留请求路径/api/login,转发到http://localhost:8080/api/login
location /api/ {
proxy_pass http://localhost:8080;
}
保留请求路径/api/login,转发到http://localhost:8080/api/login
# 带URI
核心,带/会触发Nginx的“路径替换”
移除 location 中匹配的前缀 ,然后将剩余部分拼接到 proxy_pass 的 URL 后面
一句话:保留匹配模式后的路径,拼接到代理服务器的地址后
# 例1 (正例)
location /api/ {
proxy_pass http://localhost:8080/;
}
保留匹配模式后的路径login,拼接到proxy_pass后面,http://localhost:8080/login
# 例2 (反例)
location /api {
proxy_pass http://localhost:8080/;
}
保留匹配模式后的路径/login,拼接到proxy_pass后面,http://localhost:8080//login
转发地址错误,出现//
# 例3 (反例)
location /api/ {
proxy_pass http://localhost:8080/abc;
}
保留匹配模式后的路径login,拼接到proxy_pass后面,http://localhost:8080/abclogin
转发地址错误,出现abclogin
# 例4 (正例)
location /api {
proxy_pass http://localhost:8080/abc;
}
保留匹配模式后的路径/login,拼接到proxy_pass后面,http://localhost:8080/abc/login
# 例5(正例)
location /api/ {
proxy_pass http://localhost:8080/abc/;
}
保留匹配模式后的路径login,拼接到proxy_pass后面,http://localhost:8080/abc/login
# 例6 (反例)
location /api {
proxy_pass http://localhost:8080/abc/;
}
保留匹配模式后的路径/login,拼接到proxy_pass后面,http://localhost:8080/abc//login
转发地址错误,出现//
可见,location和proxy_pass要不同时带
/,要不同时不带/不能一个带,一个不带
再加上location不带
/时,可能会出现匹配错误的情况,比如/api会匹配到apiabc所以建议location和proxy_pass同时带
/