案例资料链接:https://download.csdn.net/download/ly1h1/90745660
1.逻辑说明
1.1 逻辑示意图
# 前端请求处理逻辑图
浏览器请求流程:
1. 浏览器发起请求
├─ 开发环境(DEV)
│ ├─ 请求URL: http://192.168.0.102:3000/api/xxx
│ └─ 被Vite代理处理
└─ 生产环境
├─ 请求URL: /api/xxx
└─ 被Nginx处理
Vite代理处理(开发环境):
1. 接收 /api 开头的请求
2. 转发到 target: http://43.162.118.209:7127
3. 保留原始 /api 前缀
4. 添加 changeOrigin 和 secure:false 配置
Nginx处理(生产环境):
1. 监听 8061 端口
2. 路由匹配:
├─ / → 静态资源
│ ├─ root: C:/nginx/dist3
│ └─ 返回 index.html
└─ /api → 反向代理
├─ 转发到 http://43.162.118.209:7127
├─ 设置 Host 头
└─ 添加CORS头:
├─ Access-Control-Allow-Origin: http://43.162.118.209:8061
└─ Access-Control-Allow-Methods: GET,POST,OPTIONS
后端服务:
1. 运行在 http://43.162.118.209:7127
2. 接收来自:
├─ 开发环境: Vite代理的请求
└─ 生产环境: Nginx代理的请求
1.2 时序图
1.3 架构拓扑图
2.前端
2.1 vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
export default defineConfig({
plugins: [vue()],
server: {
host: '192.168.0.102', // 允许通过IP访问
port: 3000, // 默认端口(可自定义)
proxy: {
'/api': {
target: 'http://43.162.118.209:7127',
changeOrigin: true,
secure: false,
rewrite: (path) => path.replace(/^\/api/, '/api') // 关键修改:保留/api前缀
}
}
}
})
host:是前端开发环境下的启动地址
port:是前端开发环境下的启动端口
proxy:属于用来做跨域转换的
2.2 request.js(接口请求的方法,独立出来了)
import axios from 'axios'
import { ElMessage } from 'element-plus'
const service = axios.create({
baseURL: import.meta.env.DEV
? 'http://192.168.0.102:3000/api' // 开发环境走Vite代理
: '/api', // 生产环境走Nginx代理
timeout: 10000
})
// 请求拦截器
service.interceptors.request.use(
config => {
// 可在此添加token等全局headers
// const token = localStorage.getItem('token')
// if (token) config.headers.Authorization = `Bearer ${token}`
return config
},
error => {
console.error('Request Error:', error)
return Promise.reject(error)
}
)
// 响应拦截器
service.interceptors.response.use(
response => {
// 根据后端数据结构调整
const res = response.data
if (res.code && res.code !== 200) {
ElMessage.error(res.message || '请求失败')
return Promise.reject(res)
}
return res
},
error => {
console.error('Response Error:', error)
ElMessage.error(error.message || '服务异常')
return Promise.reject(error)
}
)
/**
* 封装GET请求
* @param {string} url
* @param {object} params
* @returns
*/
export function get(url, params = {}) {
return service({ url, method: 'GET', params })
}
/**
* 封装POST请求
* @param {string} url
* @param {object} data
* @returns
*/
export function post(url, data = {}) {
return service({ url, method: 'POST', data })
}
export function getValues() {
return service.get('/Values') // 明确使用GET
}
export default service
重点讲解
const service = axios.create({
baseURL: import.meta.env.DEV
? 'http://192.168.0.102:3000/api' // 开发环境走Vite代理
: '/api', // 生产环境走Nginx代理
timeout: 10000
})
这段代码创建了一个配置化的 Axios 实例,主要实现了:
-
环境区分:通过
import.meta.env.DEV
判断当前是开发环境还是生产环境 -
动态 baseURL:
-
开发环境:
http://192.168.0.102:3000/api
-
生产环境:
/api(对接前面
vite.config.js的配置)
-
-
全局超时设置:10秒(timeout: 10000)
2.3 App.Vue
实现业务应用,接口请求获取数据,呈现在el-table控件
<template>
<div>
<el-button type="primary" @click="fetchData">获取API数据</el-button>
<el-table :data="tableData" v-loading="loading">
<el-table-column prop="aaa" label="AAA" />
<el-table-column prop="baa" label="BAA" />
<el-table-column prop="caa" label="CAA" />
<el-table-column prop="daa" label="DAA" />
</el-table>
</div>
</template>
<script>
import { get } from './api/request'
export default {
data() {
return {
tableData: [],
loading: false
}
},
methods: {
async fetchData() {
try {
this.loading = true
const response = await get('/Values') // 使用封装的get方法
this.tableData = response.data || response // 根据实际返回结构调整
} catch (error) {
console.error('获取数据失败:', error)
} finally {
this.loading = false
}
}
}
}
</script>
3.后端
3.1 Program.cs
using Microsoft.Extensions.Options;
var builder = WebApplication.CreateBuilder(args);
// 添加必要服务(修正版)
builder.Services.AddControllers();
// 正确配置Swagger(需要先安装NuGet包)
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new() { Title = "My API", Version = "v1" });
});
// 配置CORS
builder.Services.AddCors(options =>
{
options.AddPolicy("VueFrontend", policy =>
{
policy.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod();
});
});
var app = builder.Build();
// 中间件顺序非常重要!
app.UseRouting();
app.UseCors("VueFrontend");
// 开发环境配置
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
});
}
app.UseAuthorization();
app.MapControllers();
app.Run("http://0.0.0.0:7127");
是一个典型的 ASP.NET Core Web API 的启动配置,主要包含以下核心功能:
1. 基础服务配置
-
AddControllers()
:启用 MVC 控制器,用于处理 HTTP 请求(REST API)。 -
AddEndpointsApiExplorer()
+AddSwaggerGen()
:集成 Swagger/OpenAPI,自动生成 API 文档(需安装Swashbuckle.AspNetCore
NuGet 包)。-
访问方式(开发环境):
/swagger
或/swagger/v1/swagger.json
。
-
2. CORS(跨域资源共享)配置
-
AddCors()
定义了一个名为"VueFrontend"
的策略,允许:-
任意来源(
AllowAnyOrigin
) -
任意 HTTP 方法(
AllowAnyMethod
) -
任意请求头(
AllowAnyHeader
)
-
-
UseCors("VueFrontend")
启用该策略,确保前端(如 Vue.js/React)可以跨域访问 API。
3. 中间件(Middleware)顺序
ASP.NET Core 的中间件顺序非常重要,此代码按推荐顺序配置:
-
UseRouting()
:路由匹配。 -
UseCors()
:必须在路由之后、授权之前启用 CORS。 -
UseAuthorization()
:身份认证(如 JWT)。 -
MapControllers()
:映射控制器路由。
4. 开发环境优化
-
UseSwagger()
+UseSwaggerUI()
:仅在开发环境启用 Swagger,方便调试 API。
5. 自定义运行地址
-
app.Run("http://0.0.0.0:7127")
:-
监听所有网络接口(
0.0.0.0
),而不仅仅是localhost
。 -
端口
7127
,可通过builder.Configuration
或环境变量动态配置。
-
3.2 接口代码
ValuesController.cs
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
namespace WebApplication9.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
[HttpGet]
public List<ClassModel> Get()
{
List < ClassModel > classes = new List<ClassModel> ();
for (int A = 0; A < 5; A++)
{
ClassModel classModel = new ClassModel()
{
AAA = "a" + A.ToString(),
BAA = "b" + A.ToString(),
CAA = "c" + A.ToString(),
DAA = "d" + A.ToString(),
};
classes.Add(classModel);
}
return classes;
}
}
}
-----------------------------
namespace WebApplication9
{
public class ClassModel
{
public string AAA { get; set; }
public string BAA { get; set; }
public string CAA { get; set; }
public string DAA { get; set; }
}
}
4.Nginx配置
4.1 Nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
server {
listen 8061;
server_name 43.162.118.209;
location / {
root C:/nginx/dist3;
try_files $uri $uri/ /index.html;
}
location /api {
# proxy_pass http://localhost:7127/api;
#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_cookie_flags ~ secure samesite=none;
proxy_pass http://43.162.118.209:7127;
proxy_set_header Host $host;
# CORS头(与后端保持一致)
add_header 'Access-Control-Allow-Origin' 'http://43.162.118.209:8061';
add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS';
}
}
}
1. 核心配置概述
-
工作进程:
worker_processes 1;
-
仅启用 1 个 Worker 进程,适合低负载场景,生产环境建议设为 CPU 核心数。
-
-
事件模块:
worker_connections 1024;
-
每个 Worker 进程支持 1024 个并发连接。
-
2. HTTP 服务配置
全局配置
-
include mime.types;
-
引入 MIME 类型文件,用于正确识别文件类型(如
.html
、.js
)。
-
-
default_type application/octet-stream;
-
默认响应类型为二进制流(若未匹配到 MIME 类型)。
-
Server 块
-
监听端口:
8061
,绑定到 IP43.162.118.209
。 -
静态资源服务:
nginx
复制
下载
location / { root C:/nginx/dist3; try_files $uri $uri/ /index.html; }
-
根目录:
C:/nginx/dist3
(前端项目部署路径)。 -
路由回退:
try_files
确保前端路由(如 Vue/React)直接访问子路径时返回index.html
,避免 404。
-
API 代理配置
nginx
复制
下载
location /api { proxy_pass http://43.162.118.209:7127; proxy_set_header Host $host; add_header 'Access-Control-Allow-Origin' 'http://43.162.118.209:8061'; add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS'; }
-
反向代理:将
/api
请求转发到后端服务http://43.162.118.209:7127
。 -
请求头设置:
-
Host
头传递客户端原始域名。
-
-
CORS 支持:
-
允许来自
http://43.162.118.209:8061
的跨域请求,仅开放GET/POST/OPTIONS
方法。
-