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

package.json

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

js 复制代码
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

js 复制代码
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

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)

ts 复制代码
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
        }
    }
});
相关推荐
风雨兼程^_^17 天前
Nuxt3项目的SEO优化(robots.txt,页面tdk,伪静态.html,sitemap.xml动态生成等)
前端·seo·nuxt3·服务端渲染ssr
Hao.Zhou1 个月前
Nuxt3 优雅地在一个项目中集成 PC 端、移动端多套页面
前端·nuxt3
化作繁星2 个月前
nuxt3中使用useFetch请求刷新不返回数据或返回html结构问题解决-完整nuxt3useFetchtch请求封装
vue·nuxt3·usefetch
上官熊猫3 个月前
nuxt3项目打包部署到服务器后配置端口号和开启https
前端·vue3·nuxt3
Bug从此不上门5 个月前
Nuxt3之使用lighthouse性能测试及性能优化实操
前端·javascript·性能优化·vue·fetch·nuxt3
Bessie2345 个月前
实现 Nuxt3 预览PDF文件
pdf·vue3·nuxt3
Bessie2346 个月前
实现Vue3/Nuxt3 预览excel文件
javascript·excel·vue3·nuxt3
Amd7947 个月前
使用 Nuxt Kit 检查模块与 Nuxt 版本兼容性
模块·nuxt·兼容性·版本·nuxt3·nuxt2·检查
Amd7948 个月前
使用 reloadNuxtApp 强制刷新 Nuxt 应用
状态管理·nuxt3·强制刷新·组件交互·缓存控制·路径导航·页面重载