Nginx发布Vue(ElementPlus),与.NETCore对接(腾讯云)

案例资料链接: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 的中间件顺序非常重要,此代码按推荐顺序配置:

  1. UseRouting():路由匹配。

  2. UseCors():必须在路由之后、授权之前启用 CORS。

  3. UseAuthorization():身份认证(如 JWT)。

  4. 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,绑定到 IP 43.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 方法。

5.配置安全组和入站规则

6.运行效果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值