Nginx代理快速入门案例
- 1、正向代理和反向代理的区别
- [2、 实际项目案例演示](#2、 实际项目案例演示)
🎯 我们在开发时处于不同的目的,不想让别人看到我们的项目源码,或者源码内容太大启动项目时不方便等等。又没有一种轻量化的启动方法,有的兄弟!
🎯 可以使用nginx代理,我们只需要将开发好的项目交给Nginx代理,然后启动Nginx,在浏览器中输入代理网址就能访问项目了,就这么简单!
1、正向代理和反向代理的区别
首先需要明白为什么要代理?不使用代理不行吗?
答案是:不使用代理理论上可以,但是会面临着很多问题,比如跨域(协议、域名、端口三者任意出现就会产生跨域问题)、安全、体验等一系列问题。
我们在开发时面临两个阶段:开发环境 和生产环境
开发环境使用vite 正向代理
生产环境使用Nginx反向代理
正向代理
正向代理是客户端的代理,它代表客户端向服务器发送请求。客户端知道目标服务器是谁,但需要通过代理来访问。
客户端 → 正向代理 → 互联网 → 目标服务器
也就是说我们发送的请求知道后端服务器的地址,但是后端服务器不知道我们信息。
举例说明:
前端:localhost:5173
后端:localhost:51601

登录按钮发送请求:/api/device/v1/user/login (5173端口)
但是后端接口是:http:localhost:51601/device/v1/user/login
会触发浏览器的同源策略,因为端口号不同出现跨域问题。这时无法访问后端
我们就需要在项目的vite.config.js文件,配置我们的代理

server: {
host: 'localhost',
port: 5173,
cors: true,
proxy: {
'/api/device': {
target: 'http://localhost:51601',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
configure: (proxy) => {
proxy.on('error', (err) => {
console.log('❌ API代理错误:', err)
})
}
}
}
}
/api/device/v1/user/login
这里配置了两个拦截规则,当我们请求命中**/api/device规则时,就使用代理访问,
target: 'http://localhost:51601', ------------修改请求路径
changeOrigin: true,------------ 允许跨域请求
rewrite: (path) => path.replace(/^/api/, ''), ------------重写路径将 /api/device中的 /api/**重写成 ' '
关于重写是符合自己的项目要求,也可以不重写,根据实际情况来。
前端请求流程图如下:

反向代理
Nginx就是反向代理,当我们将项目交给Nginx后不需要知道项目的端口,只需要访问Nginx代理时的端口即可,这时客户端不知道真实的后端服务器,只知道代理服务器。
客户端 → 反向代理 → 内部服务器集群
举例说明
登录按钮发送请求:/api/device/v1/user/login (5173端口)
后端接口:http:localhost:51601/device/v1/user/login
Nginx代理:
listen 8803 ; # 使用8803端口,避免与其他服务冲突
server_name localhost;
原始访问路径:localhost:5173/login
现在:localhost:8803/login

反向代理流程图:

代理对比
| 特性 | 正向代理 | 反向代理 |
|---|---|---|
| 代理对象 | 客户端 | 服务器 |
| 客户端知道目标吗 | 知道 | 不知道 |
| 目标知道客户端吗 | 不知道 | 知道(代理传递信息) |
| 配置位置 | 客户端 | 服务器端 |
| 主要目的 | 隐藏客户端、访问控制 | 负载均衡、安全、缓存 |
| 典型场景 | VPN、公司网络代理 | 网站部署、微服务网关 |
2、 实际项目案例演示
正向代理适合开发可以直接知道后端的地址,反向代理适合生产直接访问代理服务。理解了正向代理和反向代理之后,我们用一个小案例来实际演示Nginx的具体使用步骤。包括
vite配置打包路径------>构建前端项目------>配置Nginx 服务器------>启动服务访问网址
构建前端项目
import { fileURLToPath, URL } from 'node:url'
import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig(({ mode, command }) => {
const env = loadEnv(mode, process.cwd(), '')
// 判断是否是构建命令
const isBuild = command === 'build'
return {
plugins: [vue()],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
},
},
base: env.VITE_APP_BASE_URL || './',
build: {
outDir: 'dist',
assetsDir: 'assets',
sourcemap: mode === 'development',
// 只在生产构建且安装了 terser 时启用压缩
minify: isBuild && mode === 'production' ? 'terser' : false,
rollupOptions: {
output: {
chunkFileNames: 'assets/js/[name]-[hash].js',
entryFileNames: 'assets/js/[name]-[hash].js',
assetFileNames: 'assets/[ext]/[name]-[hash].[ext]'
}
},
terserOptions: isBuild && mode === 'production' ? {
compress: {
drop_console: true,
drop_debugger: true
}
} : undefined
},
server: {
host: 'localhost',
port: 5173,
cors: true,
proxy: {
'/api/device': {
target: 'http://localhost:51601',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
configure: (proxy) => {
proxy.on('error', (err) => {
console.log('❌ API代理错误:', err)
})
}
}
}
}
}
})
配置中仅关注build即可,server是正向代理,开发时使用。
build: {
outDir: 'dist',
assetsDir: 'assets',
sourcemap: mode === 'development',
// 只在生产构建且安装了 terser 时启用压缩
minify: isBuild && mode === 'production' ? 'terser' : false,
rollupOptions: {
output: {
chunkFileNames: 'assets/js/[name]-[hash].js',
entryFileNames: 'assets/js/[name]-[hash].js',
assetFileNames: 'assets/[ext]/[name]-[hash].[ext]'
}
},
outDir:将项目构建后的位置,这里是放在了项目跟目录下,构建后的文件夹名字为dist
assetsDir:静态资源子目录:指定非入口 JS/CSS 文件(如图片、字体、样式)的输出父目录
SourceMap:源码映射:仅开发环境生成(mode === 'development'),生产环境关闭
terser:代码压缩配置:仅在「生产构建 + 生产环境」且安装 terser 时启用 terser 压缩,如果项目中没有需要使用npm install组件安装
执行完后会发现在根目录有一个dist文件夹:

记住此时的目录,配置Nginx代理时只需要dist文件夹的位置即可,这里暂且认为是**/Users/Desktop/dist**
配置 Nginx 服务器
找到Nginx 文件夹中的nginx.config配置文件

我的配置方式,将nginx.conf作为全局nginx配置,因为开发的项目不止一个,可以将每个项目单独写成一个配置文件然后交给总的配置文件管理。
即将我们的项目写成单独配置文件放在apps中,如下图:

device-detection.conf配置文件如下:
# 设备检测系统前端
server {
listen 8803; # 使用8803端口,避免与其他服务冲突
server_name localhost;
# 前端静态文件目录 - 修改为你的实际路径
root /Users/Desktop/dist;
index index.html;
# Vue Router history模式支持
location / {
try_files $uri $uri/ /index.html;
# 防止点击劫持
add_header X-Frame-Options "SAMEORIGIN" always;
# 限制请求方法
if ($request_method !~ ^(GET|POST|OPTIONS|HEAD)$) {
return 405;
}
}
# API代理配置(对应后端服务端口51601)
location /api/ {
# 移除/api前缀传递给后端
rewrite ^/api/(.*)$ /$1 break;
proxy_pass http://localhost:51601;
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_set_header X-Forwarded-Proto $scheme;
# 启用CORS
add_header Access-Control-Allow-Origin "*" always;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization" always;
其中重点配置有
listen8803 监听8803端口root是重点,是项目build之后的dist文件的地址,修改本地地址的位置,要记得同步这里否则代理失败- index index.html 表示如果找不到静态资源就会进入index.html页面
API代理也比较重要,是我们在开发时vite.js配置文件中server的拦截规则
启用CORS:允许跨域请求
配置完了device-detection.conf单独文件之后,将其交给总的nginx.conf管理,这样即使有多个代理在nginx中也不会显得很乱,管理比较清晰。
worker_processes 1;
error_log /opt/homebrew/var/log/nginx/error.log;
pid /opt/homebrew/var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# 包含您的实际配置文件
include apps/*.conf;
include leadnews.conf/*.conf;
}
可以看出我这里有两个项目,放在不同的文件夹中
include apps/*.conf;include leadnews.conf/*.conf;
include apps/*.conf;意思是包括apps文件夹下所有.conf结尾的配置文件
启动代理并访问
我是使用homebrew安装的Nginx,直接执行nginx命令即可启动nginx,不同安装方式可以在cd /nginx/sbin目录下执行./nginx
在终端/cmd中执行启动命令

可以在浏览器中访问:localhost:8803/login

可以发现成功访问!看到这里你已经学会了配置nginx代理,快去动手试试吧~
