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
        }
    }
});


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/984551.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

抽象类与普通类

抽象类和普通类的区别&#xff1a; 抽象类其实就是普通类和接口&#xff08;完全抽象&#xff09;之间的设计工具。通过抽象类&#xff0c;可以更灵活地构建可扩展、可维护的类层次结构。抽象类的核心价值在于平衡代码复用和规范约束。 示例&#xff1a;

免费生成可下载ppt

1.天工AI 免费的&#xff0c;模版很少&#xff0c;效果不是很好&#xff1b; 2.Kimi 免费的&#xff0c;模版不多&#xff0c;效果还可以&#xff1b;

【解决哈希冲突】

哈希冲突 如果两个不同的 key 通过哈希函数得到了相同的索引&#xff0c;这种情况就叫做「哈希冲突」。 哈希冲突不可能避免&#xff0c;只能在算法层面妥善处理出现哈希冲突的情况。 哈希冲突是一定会出现的&#xff0c;因为这个 hash 函数相当于是把一个无穷大的空间映射到…

基于LabVIEW的脚本化子VI动态生成

该示例展示了一种利用LabVIEW VI脚本&#xff08;VI Scripting&#xff09;技术&#xff0c;通过程序化方式动态生成并替换子VI的解决方案。核心逻辑为&#xff1a;基于预定义的模板VI&#xff0c;根据用户选择的数学操作&#xff08;加法或乘法&#xff09;&#xff0c;自动生…

谷歌AI最新发布的可微分逻辑元胞自动机(DiffLogic CA)

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

如何使用Postman,通过Mock的方式测试我们的API

这篇文章将教会大家如何利用 postman&#xff0c;通过 Mock 的方式测试我们的 API。 什么是 Mock Mock 是一项特殊的测试技巧&#xff0c;可以在没有依赖项的情况下进行单元测试。通常情况下&#xff0c;Mock 与其他方法的主要区别就是&#xff0c;用于取代代码依赖项的模拟对…

pytest基础知识

pytest知识了解 pytest的基础知识了解&#xff1a;Python测试框架之pytest详解_lovedingd的博客-CSDN博客_pytest框架 (包含设置断点&#xff0c;pdb&#xff0c;获取最慢的10个用例的执行耗时) pytest-pytest.main()运行测试用例&#xff0c;pytest参数&#xff1a; pytest-…

LM Studio 替换源的方式解决huggingface.co无法访问的问题

安装软件完成之后&#xff0c;不要打开&#xff0c;打开了就直接关闭 在安装目录下&#xff0c;比如我安装在E:\Program Files\LM Studio 下面三个文件中的huggingface.co全部替换为hf-mirror.com然后再打开即可。 E:\Program Files\LM Studio\resources\app\.webpack\rende…

【含文档+PPT+源码】基于微信小程序的乡村振兴民宿管理系统

项目介绍 本课程演示的是一款基于微信小程序的乡村振兴民宿管理系统&#xff0c;主要针对计算机相关专业的正在做毕设的学生与需要项目实战练习的 Java 学习者。 1.包含&#xff1a;项目源码、项目文档、数据库脚本、软件工具等所有资料 2.带你从零开始部署运行本套系统 3.该…

五、OpenGL中Shader与C++数据传输

文章目录 一、概述二、Shader 代码文件的基本格式三、Shader的向量语法介绍四、Shader之间的数据传输五、Shader与C的数据传输uniform六、完整示例 一、概述 在 OpenGL 中&#xff0c;Shader&#xff08;着色器&#xff09;使用 GLSL&#xff08;OpenGL Shading Language&…

docker不停机部署

背景 最近做大疆项目时&#xff0c;后台更新部署时&#xff0c;机场和无人机就会掉线。设备自动重连注册时间比较长&#xff0c;应用长时间不可用。所以需要灰色发布服务。docker-compose的swarm模式可解决此问题。 服务构建脚本Dockerfile # 使用官方Java基础镜像&#xff…

工作记录 2016-12-22

工作记录 2016-12-22 更新的问题 1、修改了Job Summary的Bill Amount的Bug。 2、修改了Account #的宽度。 3、修改了Clearinghouse Status的默认查询的条件。 4、修改了Upload Files的Add File的bug。 5、Pending Pool、Missing Infos加了Write Off&#xff0c;修改了Histor…

QLoggingCategory类使用

QLoggingCategory类使用 QLoggingCategory的概述 QLoggingCategory是Qt的日志策略类&#xff1b;可以通过声明不同的日志策略对象来输出不同的日志信息。打印信息类型如下&#xff1a;宏 Q_DECLARE_LOGGING_CATEGORY(name) 定义一个返回QLoggingCategory对象函数&#xff0c;…

Linux红帽:RHCSA认证知识讲解(五)从红帽和 DNF 软件仓库下载、安装、更新和管理软件包

Linux红帽&#xff1a;RHCSA认证知识讲解&#xff08;五&#xff09;从红帽和 DNF 软件仓库下载、安装、更新和管理软件包 前言一、DNF 软件包管理基础1.1 核心操作命令安装软件包卸载软件包重新安装软件包 1.2 软件仓库原理 二、配置自定义软件仓库步骤 1&#xff1a;清理默认…

Go本地缓存设计与实现

本地缓存是一个项目中很常见的组件。在很多人的眼中就是一个简单的key-value的map存储即可实现&#xff0c;但实际上&#xff0c;设计一个本地缓存需要考虑的问题远比你想象的多&#xff0c;比如说&#xff0c;本地缓存是将数据存储在内存&#xff0c;若数据量激增突破了内存限…

通义万相2.1开源版本地化部署攻略,生成视频再填利器

2025 年 2 月 25 日晚上 11&#xff1a;00 通义万相 2.1 开源发布&#xff0c;前两周太忙没空搞它&#xff0c;这个周末&#xff0c;也来本地化部署一个&#xff0c;体验生成效果如何&#xff0c;总的来说&#xff0c;它在国内文生视频、图生视频的行列处于领先位置&#xff0c…

Jetson Xavier NX安装CUDA加速的OpenCV

我们使用SDKManager刷机完成后&#xff0c;使用jtop查看&#xff0c;发现OpenCV 是不带CUDA加速的&#xff0c;因此&#xff0c;我们需要安装CUDA加速的OpenCV&#xff0c;这样后续在使用的时候速度会快很多。 首先我们先卸载默认OpenCV sudo apt purge libopencv* -y sudo …

基于PaddleNLP使用DeepSeek-R1搭建智能体

基于PaddleNLP使用DeepSeek-R1搭建智能体 最近在学习DeepSeek&#xff0c;找到了PaddleNLP星河社区大模型&#xff0c;跟着敲写了一遍。内容来源&#xff1a;DeepSeek实战训练营&#xff1a;从云端模型部署到应用开发 - 飞桨AI Studio星河社区-人工智能学习与实训社区 本项目基…

给大家推荐8个好玩有趣的网站

1、Home Apothecary 家庭药房 https://apothecary.tips/zh Home Apothecary&#xff08;家庭药房&#xff09;结合传统中医智慧与现代科学验证&#xff0c;提供涵盖睡眠改善、免疫力提升、肠胃调理、活力增强等健康需求的天然养生饮品配方。精选安神助眠、四季调养、舒缓压力…

使用Beanshell前置处理器对Jmeter的请求body进行加密

这里我们用HmacSHA256来进行加密举例&#xff1a; 步骤&#xff1a; 1.先获取请求参数并对请求参数进行处理&#xff08;处理成String类型&#xff09; //处理请求参数的两种方法&#xff1a; //方法一&#xff1a; //获取请求 Arguments args sampler.getArguments(); //转…