外观
前端使用 Nginx 部署项目——从零开始
本文档专为零基础初学者编写,从最基础的概念讲起。 每个步骤都有详细说明、注意事项和常见错误提醒。
目录
- Nginx 是什么?(大白话解释)
- 学 Nginx 之前需要知道的基础知识
- 准备工作:你需要什么?
- Linux 基础命令(够用就行)
- 连接你的服务器(SSH)
- 安装 Nginx
- 第一个 Nginx 配置文件
- 部署你的前端项目
- 理解核心配置项
- SPA 单页应用的 history 路由配置
- 安全配置:开启 HTTPS
- Nginx 的日志与排错
- 常见问题与踩坑(初学者版)
- 完整配置模板
- 进一步学习建议
1. Nginx 是什么?(大白话解释)
Nginx(发音 "engine-x")是一个 Web 服务器软件。 通俗地说,它的工作就是:当用户在浏览器输入你的网址,Nginx 负责把网站的文件(HTML、CSS、JS、图片)通过网络发给用户的浏览器。
你可以把 Nginx 理解为"你家网站的大门口":
- 客人来了 -> Nginx 开门迎接(响应 HTTP 请求)
- 客人要商品 -> Nginx 去货架找(返回静态文件)
- 商品需要从仓库调 -> Nginx 去联系仓库(反向代理到后端)
- 客人太多 -> Nginx 维持秩序(高并发处理)
- 想装个防盗门 -> Nginx 配置 HTTPS
Nginx 不是编程语言,不是框架。它是一个服务器软件,就像 Chrome 是"浏览器软件"一样。 作为前端开发者,你要做的就是:安装它、告诉它你的前端文件在哪里、怎么处理不同的访问请求。
2. 学 Nginx 之前需要知道的基础知识
2.1 什么是服务器?
服务器就是一台 24 小时开机的电脑,放在机房或者云上(阿里云、腾讯云)。 你的前端项目文件就放在这台电脑上。Nginx 安装在这台电脑上,负责把文件发给访问者。
2.2 什么是 IP 地址和域名?
- IP 地址:服务器的门牌号,如 123.45.67.89
- 域名:好记的名字,如 www.example.com
- DNS:电话本,告诉浏览器某个域名对应哪个 IP
你可以不用域名,直接用 IP 地址访问。但生产环境通常需要域名(因为 HTTPS 证书需要域名)。
2.3 什么是端口?
端口是服务器上的"门",不同程序走不同的门:
- 80 端口:HTTP 默认端口
- 443 端口:HTTPS 默认端口 你访问 http://example.com 其实等于 http://example.com:80
2.4 什么是前后端分离?
前后端分离的架构中,Nginx 扮演"中间人"的角色: 浏览器请求 -> Nginx -> 如果是静态文件,直接返回 -> 如果是 API 请求,转发给后端服务器 -> 后端处理完,Nginx 把结果返回浏览器
2.5 常用术语速查表
| 术语 | 大白话解释 |
|---|---|
| Web 服务器 | 存放网站文件并提供网络访问的软件 |
| 反向代理 | 浏览器请求 Nginx,Nginx 再去请求后端,再返回结果 |
| 静态文件 | 不会变化的文件:HTML、CSS、JS、图片 |
| 负载均衡 | 有多个后端时,Nginx 把请求分发给不同后端 |
| SSL/TLS | 加密协议,让 HTTP 变成 HTTPS |
3. 准备工作:你需要什么?
3.1 必备清单
| 项目 | 说明 | 费用参考 |
|---|---|---|
| 一台云服务器 | 阿里云/腾讯云/华为云的轻量应用服务器 | 约 50-100 元/月 |
| SSH 连接工具 | 用来远程操作服务器 | 免费 |
| 一个域名(可选) | 如 example.com | 约 30-60 元/年 |
| 你的前端项目 | 写好的 Vue/React 项目 | 已有 |
3.2 购买云服务器后要做的第一件事
登录云服务商的控制台,找到"安全组"或"防火墙",添加入站规则:
- 端口 80(HTTP):允许所有人访问
- 端口 443(HTTPS):允许所有人访问
- 端口 22(SSH):允许你连接(默认已有)
安全组是新手最容易忽略的配置!很多人装好 Nginx 后打不开网页,就是因为安全组没放行 80 端口。
3.3 什么是 SSH?
SSH 是"安全外壳协议",用来从你的电脑远程连接到服务器的命令行界面。 连接上之后,你就可以在命令行操作服务器,就像坐在它面前一样。
4. Linux 基础命令(够用就行)
你不需要成为 Linux 专家,以下命令足够完成 Nginx 相关操作:
bash
pwd # 查看当前目录路径
ls -la # 列出当前目录所有文件(包含隐藏文件)
cd /var/www/ # 切换到指定目录
cd .. # 返回上级目录
cat file.txt # 查看文件内容
nano file.txt # 编辑文件(初学者友好)
cp source.txt dest.txt # 复制文件
mv old.txt new.txt # 重命名/移动
rm file.txt # 删除文件
mkdir mydir # 创建目录
sudo chmod 755 file # 修改权限
sudo chown www-data:www-data /var/www/myapp # 修改所有者
# 查看 Nginx 相关进程
ps aux | grep nginx
# 查看日志
tail -f /var/log/nginx/error.log强烈建议初学者先用 nano 编辑文件。它比 vim 直观得多,界面底部有快捷键提示。
5. 连接你的服务器(SSH)
Windows 系统
bash
# 打开 Terminal 或 PowerShell,输入:
ssh root@你的服务器IP
# 例如:ssh root@123.45.67.89
# 然后输入密码(输入时不会显示),回车
# 看到 root@your-server:~# 就表示连接成功了macOS / Linux 系统
bash
ssh root@你的服务器IP常见连接问题
- 第一次连接会出现 "Are you sure?" 提示,输入 yes 回车
- 连接不上?检查:
- 服务器是否开机
- IP 地址是否正确
- 安全组是否放行了 22 端口
6. 安装 Nginx
6.0 Nginx 的版本策略(先看懂再安装)
Nginx 开源版同时维护两条分支(依据 nginx.org 官方说明):
| 分支 | 版本号规律 | 更新节奏 | 适合谁 |
|---|---|---|---|
| mainline(主线版) | 中间数字为奇数,如 1.31.x | 约每 1-2 个月,含最新功能+安全修复 | 官方推荐大多数生产环境使用 |
| stable(稳定版) | 中间数字为偶数,如 1.30.x | 约每年一次大版本,只回移植关键修复 | 对稳定性要求极严、不想跟新功能的环境 |
截至 2026 年中,主线为 1.31.x、稳定为 1.30.x(1.30.0 于 2026-04 发布,带来了 Early Hints、后端 HTTP/2、上游 sticky 会话等新特性)。⚠️ 注意:Linux 发行版自带的 apt/yum 源里的 Nginx 往往是落后一两个大版本的旧版(如 Ubuntu 仓库常见的 1.24.x),需要新特性或及时的安全补丁时,应改用 nginx.org 官方仓库安装。
6.1 Ubuntu/Debian 系统
bash
# 第一步:更新软件包列表
sudo apt update
# 第二步:安装 Nginx
sudo apt install nginx -y
# 第三步:验证是否安装成功
nginx -v
# 例如显示:nginx version: nginx/1.24.0(发行版自带源的版本,
# 版本号取决于你的 Ubuntu 版本,不一定是最新版)6.2 CentOS/RHEL 系统
bash
sudo yum install nginx -y
nginx -v6.3 启动 Nginx
bash
sudo systemctl start nginx # 启动
sudo systemctl enable nginx # 设置开机自启
sudo systemctl status nginx # 查看状态6.4 验证 Nginx 是否正常运行
在浏览器地址栏输入你的服务器 IP 地址。 如果看到 "Welcome to nginx" 的页面,恭喜你,安装成功了!
如果浏览器提示"无法访问此网站":检查安全组是否放行了 80 端口。 如果看到的是其他内容:可能 80 端口已被其他程序占用。
7. 第一个 Nginx 配置文件
7.1 Nginx 配置文件在哪?
bash
/etc/nginx/ # Nginx 配置目录
/etc/nginx/nginx.conf # 主配置文件
/etc/nginx/sites-available/ # 站点配置(可用)
/etc/nginx/sites-enabled/ # 站点配置(已启用)
/var/log/nginx/access.log # 访问日志
/var/log/nginx/error.log # 错误日志
/var/www/html/ # 默认网站目录7.2 创建你的第一个 HTML 文件
bash
sudo mkdir -p /var/www/myapp
sudo nano /var/www/myapp/index.html粘贴以下内容:
html
<!DOCTYPE html>
<html>
<head>
<title>我的第一个 Nginx 网站</title>
</head>
<body>
<h1>Hello World! Nginx 配置成功!</h1>
<p>这是我的第一个 Nginx 网站。</p>
</body>
</html>7.3 创建第一个 Nginx 配置
bash
sudo nano /etc/nginx/sites-available/myapp粘贴以下内容:
nginx
server {
listen 80;
server_name _; # _ 表示匹配所有域名
root /var/www/myapp;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}7.4 启用这个站点
bash
# 创建软链接到 sites-enabled
sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/
# 测试配置语法(每次修改后都要执行!)
sudo nginx -t
# 看到 "test is successful" 再继续
# 重载 Nginx 使配置生效
sudo systemctl reload nginx7.5 验证
在浏览器中访问你的服务器 IP,应该看到 "Hello World!" 页面。
如果页面没出来,按顺序排查:
- sudo systemctl status nginx # Nginx 在运行吗?
- sudo tail -f /var/log/nginx/error.log # 看错误日志
- ls -la /var/www/myapp/index.html # 文件存在吗?
- sudo chmod 755 /var/www/myapp # 权限对吗?
7.6 配置文件的组织结构:include 链
你只往 sites-available 放了一个文件,Nginx 为什么就认识它?因为主配置是一层层 include 进来的(Debian/Ubuntu 打包的默认 nginx.conf):
/etc/nginx/nginx.conf # 主入口
└── http {
└── include /etc/nginx/conf.d/*.conf
└── include /etc/nginx/sites-enabled/* # ← 你的软链接在这里被加载
}sites-available(可用)和 sites-enabled(已启用)是 Debian 系发行版的打包约定,nginx 本身不认识这两个目录名,CentOS/RHEL 默认只用 conf.d/。所以给 CentOS 写教程的文章会让你把配置直接放 /etc/nginx/conf.d/myapp.conf——两者只是放文件的目录不同,内容写法完全一样。
常用命令行工具(比 systemctl 更直接,nginx -t 在 7.4 已见过):
bash
nginx -t # 只检查配置语法与语义,不重启(务必熟记)
nginx -s reload # 平滑重载配置(systemctl reload 底层就是它)
nginx -s stop # 立即停止
nginx -s quit # 处理完当前请求后优雅退出
nginx -V # 查看编译参数:装了哪些模块、配置文件路径在哪💡 nginx -t 为什么重要:reload 前 Nginx 会先解析新配置,如果解析失败,旧配置继续工作;但 stop + 错误配置会让服务彻底起不来。所以任何改动都先 -t 再 reload,这是 Nginx 运维的第一安全习惯。
8. 部署你的前端项目
8.1 构建项目
bash
# 在你本地电脑上执行
npm run build
# 构建完成后会生成 dist/ 目录
ls dist/
# index.html assets/ favicon.ico8.2 上传到服务器
bash
# 方式一:scp(最简单)
scp -r dist/* root@你的服务器IP:/var/www/myapp/
# 方式二:rsync(推荐,只传改动过的文件)
rsync -avz --delete dist/ root@你的服务器IP:/var/www/myapp/
# 上传后修正权限(非常重要!)
sudo chown -R www-data:www-data /var/www/myapp/8.3 更新 Nginx 配置指向你的项目
nginx
server {
listen 80;
server_name your-domain.com; # 换成你的域名或 IP
root /var/www/myapp;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}注意这里 try_files 的最后一个参数从 =404 变成了 /index.html。 这是因为 SPA 应用需要把所有路径都指向 index.html,由前端路由来处理。
8.4 测试并重载
bash
sudo nginx -t
sudo systemctl reload nginx权限问题是新手最常遇到的坑。如果上传后页面显示 403 Forbidden,99% 是文件权限问题。 解决方案:chown -R www-data:www-data /var/www/myapp/
9. 理解核心配置项
9.1 server 块
每个 server 块定义一个"虚拟主机":
nginx
server {
listen 80; # 监听 80 端口
server_name example.com; # 这个域名来的请求才处理
root /var/www/myapp; # 网站文件目录
index index.html; # 默认首页文件名
}9.2 location 块
location 根据 URL 路径匹配不同的处理方式:
nginx
location / {
# 所有请求都到这里
}
location /api/ {
# API 请求转发到后端
proxy_pass http://localhost:3000/;
}
location ~* \.(jpg|png|css|js)$ {
# 正则匹配:图片、CSS、JS 文件
expires 30d;
}9.3 try_files——最重要的指令
nginx
try_files $uri $uri/ /index.html;
# 访问 /user/123 时:
# 1. 查找 /var/www/myapp/user/123 -> 不存在
# 2. 查找 /var/www/myapp/user/123/ -> 不存在
# 3. 返回 /var/www/myapp/index.html -> 前端路由处理9.4 root vs alias
nginx
location /app/ {
root /var/www; # 实际路径:/var/www/app/
}
location /app/ {
alias /var/www/; # 实际路径:/var/www/
}初学者建议统一用 root,alias 容易配错路径。 ⚠️ 内部机制:用 root 时,Nginx 把完整 URI 拼接到 root 后面(/app/x.js -> /var/www/app/x.js);用 alias 时,Nginx 把 location 前缀替换成 alias 的值。所以 alias 结尾要不要带
/、location 结尾要不要带/必须严格对应,否则就会出现文件名多一段/少一段的经典 404。
9.5 Gzip 压缩:静态站点提速第一课
Nginx 的 ngx_http_gzip_module 是响应过滤器,官方文档称开启后"通常能把传输数据体积减少一半甚至更多"。前端产物(JS/CSS/HTML)文本占比极高,收益非常明显。
nginx
http {
gzip on; # 默认是 off,必须显式开启
gzip_min_length 1k; # 默认 20 字节;小于 1k 的文件压缩收益抵不上 CPU 开销
gzip_comp_level 5; # 1-9,默认 1。5-6 是体积/CPU 的常见平衡点
gzip_types text/css application/javascript application/json image/svg+xml;
# text/html 无条件压缩,不用写进 types
gzip_vary on; # 输出 Vary: Accept-Encoding,帮 CDN 正确缓存
}| 指令 | 默认值 | 说明 |
|---|---|---|
gzip | off | 总开关 |
gzip_comp_level | 1 | 压缩级别 1-9,越高越省流量越费 CPU |
gzip_min_length | 20 | 低于此长度不压缩 |
gzip_types | text/html | 额外要压缩的 MIME 类型;* 匹配所有 |
gzip_vary | off | 是否添加 Vary: Accept-Encoding 响应头 |
⚠️ 两个官方文档明确提醒的点:① 图片/字体(woff2 等)本身已是压缩格式,不要加入 gzip_types;② HTTPS 下对"含敏感数据的动态响应"开启压缩存在 BREACH 攻击风险,纯静态资源无此顾虑,给登录接口等动态响应加
gzip off即可。
💡 更进一步:前端构建工具(Vite 的 vite-plugin-compression、Webpack 的 compression-webpack-plugin)可以在构建时直接生成 .gz 文件,Nginx 用 gzip_static on 直接发送预制文件,零运行时 CPU 开销(需 --with-http_gzip_static_module,发行版包一般已编译)。
9.6 反向代理必配的请求头
第 8/10 章的 location /api/ { proxy_pass ... } 只是"能转发",要让后端拿到真实信息,还需要一组 proxy_set_header:
nginx
location /api/ {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host; # 让后端看到原始域名,而不是 127.0.0.1:8080
proxy_set_header X-Real-IP $remote_addr; # 客户端真实 IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 完整代理链 IP 列表
proxy_set_header X-Forwarded-Proto $scheme; # 客户端用的是 http 还是 https
}为什么需要:经过代理后,后端看到的 TCP 对端永远是 Nginx 自己。不传 X-Forwarded-For,后端日志里所有用户的 IP 都是 127.0.0.1;不传 X-Forwarded-Proto,后端生成的重定向/链接可能错用 http scheme。Express 的 app.set('trust proxy', ...) 等框架开关就是专门消费这些头的。
💡 proxy_pass 末尾有没有 / 决定 URI 处理方式(内部机制):
proxy_pass http://127.0.0.1:8080;(不带 URI)→ 原始 URI 完整透传:/api/user到后端仍是/api/userproxy_pass http://127.0.0.1:8080/;(带/)→ 剥掉 location 前缀:/api/user变成/user这就是第 9.2 节示例里proxy_pass带/的含义——后端接口本身不挂在/api前缀下时,靠它做前缀剥离。
10. SPA 单页应用的 history 路由配置
10.1 为什么要特别配置?
Vue Router 或 React Router 的 history 模式下:
- 页面内跳转:/ -> /user -> /about,没问题
- 直接访问 /user/123 或 F5 刷新:Nginx 找 /user/123 文件 -> 找不到 -> 404
10.2 标准解决方案
nginx
server {
listen 80;
server_name example.com;
root /var/www/myapp;
index index.html;
# 核心:所有非文件路径都指向 index.html
location / {
try_files $uri $uri/ /index.html;
}
# 静态资源长期缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2?)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# API 转发
location /api/ {
proxy_pass http://127.0.0.1:8080/;
}
}注意:nginx 按“最长前缀匹配”选择 location。location /api/ 比 location / 更长,所以 /api 请求会自动命中 location /api/,与书写顺序无关(只有正则 location ~ 才按书写顺序匹配,第一个命中的生效)。
10.3 子路径部署
如果网站部署在子路径(如 /app/):
nginx
server {
listen 80;
server_name example.com;
location /app/ {
alias /var/www/myapp/;
try_files $uri $uri/ /app/index.html;
}
}同时在前端项目设置:
- Vue 3:vite.config.ts 中 base: "/app/"
- React:package.json 中 "homepage": "/app/"
10.4 静态资源缓存的内部机制:expires 与 add_header 怎么配合
浏览器缓存分两档(对应 HTTP 协议的两代机制):
| 档位 | 响应头 | 行为 | 适用 |
|---|---|---|---|
| 强缓存 | Cache-Control: public, max-age=31536000 | 有效期内不发请求,直接用本地副本 | 带 hash 的 JS/CSS/图片 |
| 协商缓存 | Last-Modified / ETag | 发请求问服务器"变了吗",没变返回 304(不传 body) | Nginx 对静态文件自动支持,默认开启 |
Nginx 里 expires 1y; 会同时改写 Expires 和 Cache-Control 两个头(官方 ngx_http_headers_module 的行为);add_header Cache-Control "public, immutable" 则是原样追加头字段。三个注意事项:
- ⚠️ add_header 的继承陷阱:
add_header只写进本层的定义就"断根"——如果location /里写了一个add_header,server/http 层的所有add_header在这个 location 就全部失效。这是"配了安全头却不生效"的头号原因(Nginx 官方文档说明 add_header 从当前层级继承,一旦本层出现 add_header 就不再向上继承)。 - ⚠️ 只对特定状态码生效:
expires/add_header默认只响应 200、201、204、206、301、302、303、304、307、308;想对 4xx/5xx 也加头,要写add_header X-Frame-Options "DENY" always;。 - 💡
immutable是告诉浏览器"有效期内连 F5 强刷都不发条件请求",只配带内容 hash 的文件名(如index-a1b2c3.js);index.html 永远不能加强缓存,否则每次发版用户都要手动清缓存才能看到新页面(对应第 13 章问题 5)。
11. 安全配置:开启 HTTPS
11.1 为什么要用 HTTPS?
- 浏览器标记"不安全"影响用户信任
- 用户数据(密码、支付信息)在传输中加密
- 很多新特性(如 Service Worker)需要 HTTPS
11.2 使用 Certbot 自动配置(推荐初学者使用)
bash
# 安装 Certbot
sudo apt install certbot python3-certbot-nginx
# 获取证书并自动配置 Nginx
sudo certbot --nginx -d example.com -d www.example.com
# 按提示输入邮箱、同意协议
# 完成后访问 https://example.com 就有 HTTPS 了
# 测试自动续期是否正常
sudo certbot renew --dry-run如果没有域名,不能用 HTTPS(Let's Encrypt 需要域名验证)。 Certbot 会自动修改你的 Nginx 配置并设置定时续期任务,你不需要手动操作。
12. Nginx 的日志与排错
12.1 日志文件位置
bash
/var/log/nginx/access.log # 谁访问了什么(调式用)
/var/log/nginx/error.log # 错误信息(排查问题用)12.2 查看日志
bash
# 查看最新的几条错误
tail -f /var/log/nginx/error.log
# 查看访问日志
tail -f /var/log/nginx/access.log
# 查看特定时间段的日志
grep "2026/06/11" /var/log/nginx/error.log12.3 排错基本流程
页面打不开?
|
+-- 浏览器提示"无法访问" -> 检查安全组 80 端口
|
+-- 浏览器显示 403 Forbidden -> 文件权限问题,chown www-data
|
+-- 浏览器显示 404 Not Found -> 检查 try_files + 文件路径
|
+-- 浏览器显示 502 Bad Gateway -> 后端没启动或连不上
|
+-- 页面显示旧内容 -> 浏览器缓存,配置 HTML 不缓存12.4 读懂一行 access.log
默认 combined 格式的一行长这样:
123.45.67.89 - - [01/Sep/2026:10:00:00 +0800] "GET /assets/index-a1b2c3.js HTTP/2.0" 200 45678 "https://example.com/" "Mozilla/5.0 ..."| 字段 | 含义 | 排错用法 |
|---|---|---|
$remote_addr | 客户端 IP | 有代理时这里可能是 CDN/SLB 的 IP(见 9.6 的 X-Forwarded-For) |
| 请求行 | 方法 + URI + 协议 | 看到 HTTP/1.0 往往是探针/扫描器 |
| 状态码 | HTTP 响应码 | 499 表示客户端等不及主动断开(Nginx 特有码),后端慢时会大量出现 |
$body_bytes_sent | 响应体字节数 | 配合 gzip 对比体积 |
| Referer / User-Agent | 来源页 / 浏览器 | 定位爬虫、盗链 |
💡 自定义日志还能加"性能字段"定位慢请求:log_format perf '$remote_addr [$time_local] "$request" $status $request_time $upstream_response_time' 然后在 access_log 里引用 format=perf。$request_time 是请求总耗时(秒,含网络传输),$upstream_response_time 是后端处理耗时——两者差距大说明问题在带宽/客户端,接近说明问题在后端(变量含义以 nginx.org ngx_http_log_module 文档为准)。
13. 常见问题与踩坑(初学者版)
问题 1:访问 IP 显示"无法访问此网站"
原因:安全组(防火墙)没放行 80 端口 解决:登录云服务商控制台,添加入站规则:端口 80,来源 0.0.0.0/0
问题 2:显示 403 Forbidden
原因:Nginx 用户(www-data)没有文件权限 解决:
bash
sudo chown -R www-data:www-data /var/www/myapp/
sudo chmod -R 755 /var/www/myapp/问题 3:点击链接正常,刷新就 404
原因:SPA 的 history 路由没配 try_files 解决:在 location / 中添加 try_files $uri $uri/ /index.html;
问题 4:修改配置后网站全打不开了
原因:配置语法错误,Nginx 重载失败 解决:
bash
sudo nginx -t # 看具体错误在哪一行
# 修正后重新
sudo nginx -t
sudo systemctl reload nginx问题 5:部署新版本后用户还是旧页面
原因:浏览器缓存了 HTML 文件 解决:让 HTML 不缓存,JS/CSS 用 hash 文件名:
nginx
location / {
add_header Cache-Control "no-cache, no-store, must-revalidate";
try_files $uri $uri/ /index.html;
}问题 6:API 代理一切正常,WebSocket 连不上
原因:proxy_pass 默认用 HTTP/1.0 且不透传 Upgrade 握手头,WebSocket 握手(Connection: Upgrade / Upgrade: websocket)直接被 Nginx 丢弃,表现为连接不断 1006 断开。 解决(三行缺一不可,见 nginx.org ngx_http_proxy_module 文档):
nginx
location /ws/ {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1; # 默认 1.0,不支持 keep-alive/Upgrade
proxy_set_header Upgrade $http_upgrade; # 透传客户端的 Upgrade 头
proxy_set_header Connection "upgrade"; # 完成协议切换握手
proxy_read_timeout 3600s; # 空闲连接别被默认 60s 超时掐断
}问题 7:上传大图片/附件报错,Nginx 直接返回 413
原因:client_max_body_size 默认 1m,超过就拒收,请求根本到不了后端。 解决:
nginx
client_max_body_size 20m; # 放在 http/server/location 层均可14. 完整配置模板
nginx
# HTTP -> HTTPS 跳转
server {
listen 80;
server_name example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com;
# SSL 证书
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
root /var/www/myapp;
index index.html;
# API 转发
location /api/ {
proxy_pass http://127.0.0.1:8080/;
}
# SPA 路由
location / {
try_files $uri $uri/ /index.html;
}
# 静态资源缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}⚠️ 关于模板里的
listen 443 ssl http2;:从 Nginx 1.25.1 起,listen参数形式的http2已被标记为过时(obsolete),官方推荐的现代写法是拆开写——listen 443 ssl;另起一行http2 on;(见 nginx.org ngx_http_v2_module 文档的示例配置)。老写法在 1.29/1.30/1.31 上仍可用,但新项目建议用新写法。 💡 想再快一步:在 443 的 server 块里加listen 443 ssl quic;+http3 on;(1.25.1 引入 HTTP/3 支持,需证书与 UDP 443 放行),并在 http 块开启第 9.5 节的 gzip。
15. 进一步学习建议
你已经学会的
- Nginx 是什么、能做什么
- 购买和连接云服务器
- 安装和启动 Nginx
- 创建 Nginx 配置
- 部署前端项目
- 配置 SPA history 路由
- 开启 HTTPS
- 查看日志和排查问题
接下来可以学的
- Gzip 压缩——减小文件体积,加快加载速度
- 反向代理——转发 API 请求到后端
- 缓存策略——浏览器缓存 + Nginx 缓存
- 负载均衡——多个后端分担压力
- WebSocket——实时通信配置
- 性能调优——worker 数量、连接数等
最重要的三句话
- root 指向你的前端文件目录
- try_files 解决 SPA 刷新 404
- 每次改配置先 nginx -t,再 reload
记住这三句话,你已经可以完成 90% 的前端部署工作了。