当前位置: 首页 > news >正文

Nuxt3 ssr build/dev时区分不同的环境

package.json

  "scripts": {
    "build": "nuxt build --dotenv .env.prod",
    "build:dev": "nuxt build --dotenv .env.dev",
    "postbuild": "mv -f .output ./dist/.output", //支持自定义文件名
    "dev": "nuxt dev --dotenv .env.dev",
    "dev:prod": "nuxt dev --dotenv .env.prod",
  }

.env.dev

VITE_BASE_PC_URL=http://pc.dev.com/api
VITE_BASE_MOBILE_URL=http://m.dev.com/api
VITE_API_KEY=675f3e7464bdfxxx
VITE_API_IV=2fd454e95cde8xxx

.env.prod

VITE_BASE_PC_URL=http://pc.prod.com/api
VITE_BASE_MOBILE_URL=http://m.prod.com/api
VITE_API_KEY=675f3e7464bdfxxx
VITE_API_IV=2fd454e95cde8xxx

nuxt.config.ts

export default defineNuxtConfig({
  runtimeConfig: {
	// 私有环境变量,仅服务端可访问
    apiKey: process.env.VITE_API_KEY,
    apiIV: process.env.VITE_API_IV,
    pcURL: process.env.VITE_BASE_PC_URL,
    mobileURL: process.env.VITE_BASE_MOBILE_URL,
  }
})

plugins/axiosPlugin.ts(服务端/客户端使用runtimeConfig.pcURL)

import axios from 'axios';
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse, InternalAxiosRequestConfig, AxiosRequestHeaders } from 'axios';
import CryptoJS from 'crypto-js';

import { defineNuxtPlugin } from '#app';

// 加密函数
function encrypt(plainText: string, key: string, iv: string): string {
    const keyHex = CryptoJS.enc.Utf8.parse(key);
    const ivHex = CryptoJS.enc.Utf8.parse(iv);
    const encrypted = CryptoJS.AES.encrypt(plainText, keyHex, {
        iv: ivHex,
        mode: CryptoJS.mode.CBC,
        padding: CryptoJS.pad.Pkcs7
    });
    return encrypted.ciphertext.toString(CryptoJS.enc.Base64);
}

export default defineNuxtPlugin(() => {
    const runtimeConfig = useRuntimeConfig();
    const deviceType = useDeviceType(); 
    const baseURL = deviceType?.type.value === 'pc' ? (runtimeConfig?.pcURL || process.env.VITE_BASE_PC_URL) : (runtimeConfig?.mobileURL || process.env.VITE_BASE_MOBILE_URL);
    const axiosInstance: AxiosInstance = axios.create({
        baseURL: baseURL,
        timeout: 30000, // 请求超时时间
    });

    let customHeadersConfig: Record<string, string> = {};

    // 请求拦截器
    axiosInstance.interceptors.request.use(
        (config: InternalAxiosRequestConfig) => {
            if (!config.headers) {
                config.headers = {} as AxiosRequestHeaders;
            }

            config.headers['Content-Type'] = 'application/json;charset=UTF-8';
            const plainText = String(new Date().getTime());
            const apiKey = (runtimeConfig.apiKey || process.env.VITE_API_KEY);
            const apiIV = (runtimeConfig.apiIV || process.env.VITE_API_IV);
            // 检查环境变量是否定义
            if (!apiKey || !apiIV) {
                throw new Error('API 密钥或 IV 未定义');
            }
            const encryptedText = encrypt(plainText, apiKey, apiIV);
            config.headers['Token'] = encryptedText;

            for (let key in customHeadersConfig) {
                // config.headers[key] = customHeadersConfig[key];
                if (customHeadersConfig[key] === '') {
                    delete config.headers[key];
                } else {
                    config.headers[key] = customHeadersConfig[key];
                }
            }

            return config;
        },
        (error) => {
            console.error('请求错误:', error.message || '未知错误');
            return Promise.reject(error);
        }
    );

    // 响应拦截器
    axiosInstance.interceptors.response.use(
        (response: AxiosResponse) => response.data,
        (error) => {
            if (error.response) {
                console.log(`错误信息: ${error.response?.data?.message}`)
                // switch (error.response.status) {
                //     case 400:
                //         console.log('未授权,请访问最新');
                //         break;
                //     case 401:
                //         console.log('未授权,请登录');
                //         break;
                //     case 404:
                //         console.log('请求资源不存在');
                //         break;
                //     case 500:
                //         console.log('服务器内部错误');
                //         break;
                //     default:
                //         console.log(`未知错误: ${error.response.status}`);
                //         break;
                // }
            } else {
                console.log(`网络错误或其他错误: ${error}`);
            }
            return Promise.reject(error);
        }
    );

    // 提取请求类型检查逻辑
    function handleRequestType(url: string, params: any, type: string, customConfig?: {}) {
        customHeadersConfig = customConfig || {};
        if (type.toUpperCase() === 'GET') {
            return axiosInstance.get(url, { params, ...customConfig });
        } else if (type.toUpperCase() === 'POST') {
            return axiosInstance.post(url, params, customConfig);
        } else {
            throw new Error('不支持的请求类型');
        }
    }

    return {
        provide: {
            customRequest: (url = '', params = {}, type = 'POST', customConfig?: {}) => {
                return handleRequestType(url, params, type, customConfig);
            },
            apiAxios: axiosInstance
        }
    }
});


相关文章:

  • Unity 基础知识总结(持续更新中...)
  • golang从入门到做牛马:第七篇-Go语言常量-不可变的“守护者”
  • 数据清洗级可视化中,Pandasnumyp的主要作用
  • 02C#基本结构篇(D1_基本语法)
  • 使用hutool封装http请求
  • 工厂模式加策略模式 -- 具体实现
  • 若依RuoYi-Cloud-Plus微服务版(完整版)前后端部署
  • 种子填充(Floodfill、泛滥填充、洪水填充) 算法c++模板
  • 固定表头、首列 —— uniapp、vue 项目
  • C#主流日志库深度对比:NLog、log4net与Serilog如何选择?
  • Qt 元对象系统
  • PyCharm 接入 DeepSeek、OpenAI、Gemini、Mistral等大模型完整版教程(通用)!
  • 《Mycat核心技术》第19章:基于MySQL实现读写分离
  • [数据结构]并查集--C++版本的实现代码
  • 【AI】神经网络|机器学习——图解Transformer(完整版)
  • Python数据分析之数据分析工具
  • 【C语言】--- 动态内存管理详解
  • 转自南京日报:天洑软件创新AI+仿真技术变制造为“智造
  • 网络安全反渗透 网络安全攻防渗透
  • 【性能测试】Jmeter详细操作-小白使用手册(2)
  • 云南工程建设信息网站/产品线上营销有哪些方式
  • 只有做推广才能搜索到网站吗/快速排名优化推广排名
  • 湖北省电力建设三公司网站/每日重大军事新闻
  • 怎么看网站有没有做地图/网络营销试卷
  • 网站简历导出/批量关键词排名查询工具
  • 做天猫还是做网站推广/怎么让某个关键词排名上去