当前位置: 首页 > 知识库问答 >
问题:

前端 - 求助,如何解决vite.config.js代理配置失效问题?

酆君墨
2024-11-16

如何解决vite.config.js代理配置失效问题?
问题描述:一个前后端分离项目,前端为vue3+vite5+uniapp项目,
后端接口为http://47.93.153.78:8080/code,微信小程序中可以访问的到,但是H5中会显示跨域问题
Access to XMLHttpRequest at 'http://47.93.153.78:8080/code' from origin 'http://localhost:7001' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
然后我这边去做代理配置, 其中proxy替换VITE_APP_BASE_API (/dev-api) 没有生效,找了半天没找到原因,求助大佬帮忙看一下


import { defineConfig } from 'vite'
import uni from '@dcloudio/vite-plugin-uni'
import { loadEnv } from 'vite'
import path from 'node:path'
import UnoCSS from 'unocss/vite'
import dayjs from 'dayjs'
import svgLoader from 'vite-svg-loader'
// 打包后,会在根目录下生成一个 stats.html文件
import { visualizer } from 'rollup-plugin-visualizer'
// 通过监听文件修改,自动重启 vite 服务  最常用的场景就是监听 vite.config.js 和 .env.development 文件,修改 vite 配置文件和环境配置文件,是需要重启 vite 才会生效
import ViteRestart from 'vite-plugin-restart'
import AutoImport from 'unplugin-auto-import/vite'
import VueSetupExtend from 'vite-plugin-vue-setup-extend'
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
import viteCompression from 'vite-plugin-compression'
// import ViteImagemin from 'vite-plugin-imagemin'
import autoprefixer from 'autoprefixer'
import UniPages from '@uni-helper/vite-plugin-uni-pages'
import UniLayouts from '@uni-helper/vite-plugin-uni-layouts'

// 自定义插件方法
const htmlPlugin = () => {
    return {
        name: 'html-transform',
        transFormIndexHtml(html) {
            return html.replace('%BUILD_DATE%', dayjs().format(''))
        },
    }
}

// unplugin-vue-components uniapp 不支持,uniapp 使用easycom的方式自动引入组件,不需要这个vite插件

export default ({ mode }) => {
    // mode区分生产环境还是开发环境
    // process.cwd() 获取当前文件的目录和地址
    // loadEnv 返回当前环境env文件中额外定义的变量

    const env = loadEnv(mode, path.resolve(process.cwd()))
    console.log(env)

    return defineConfig({
        plugins: [
            UniPages({
                exclude: ['**/components/**/**.*'],
                routeBlockLang: 'json5', // 虽然设了默认值,但是vue文件还是要加上 lang="json5", 这样才能很好地格式化
                homePage: 'pages/home-page/index',
                subPackages: ['src/pages-sub'], // 这是个数组,可以写多个
            }),
            UniLayouts(),
            // UniXXX 需要在 Uni 之前引入
            uni(),
            // 在 Vite 驱动的 uni-app 上使用基于文件的路由系统。
            UnoCSS(),
            htmlPlugin(),
            svgLoader(),
            // 打包分析插件 打包后,会在根目录下生成一个 stats.html文件
            visualizer(),
            ViteRestart({
                // 修改vite.config.ts 不用手动重启vite就能生效
                restart: ['vite.config.ts'],
            }),
            // vue3等插件hooks自动引入
            // 支持vue, vue-router, vue-i18n, @vueuse/head, @vueuse/core等自动引入
            AutoImport({
                imports: ['vue'],
                // 可以选择auto-import.d.ts生成的位置,使用ts建议设置为src/auto-import.d.ts
                dts: 'src/auto-import.d.ts',
            }),
            // 在使用setup语法糖的时候没办法直接为组件定义name,需要使用两个script标签来完成
            // 使用vite-plugin-vue-setup-extend
            // <script lang="ts" setup name="自定义name">
            VueSetupExtend(),
            createSvgIconsPlugin({
                // 指定svg图标 保存的文件夹路径,
                iconDirs: [path.resolve(process.cwd(), 'src/assets/svg')],
                // 指定symbolId格式
                symbolId: 'icon-[dir]-[name]',
            }),
            // 会多出一些.gz文件,如xxx.js.gz,这里默认是不会删除xxx.js文件的,如果想删除也可以增加配置
            // vite-plugin-compression是一个基于Vite的插件,用于gzip或Brotli压缩你的资源,从而减少页面的加载时间和网络带宽,提高用户访问速度和体验。
            viteCompression(),
        ],

        css: {
            postcss: {
                plugins: [
                    // 前端开发中,为兼容所有浏览器,部分CSS属性需要加上不同的浏览器前缀
                    autoprefixer({
                        // 指定目标浏览器
                        overrideBrowserslist: ['> 1%', 'last 2 versions'],
                    }),
                ],
            },
        },

        resolve: {
            // 配置路径别名
            alias: {
                '@': path.join(process.cwd(), './src'),
            },
        },

        server: {
            // host: '0.0.0.0',
            // hmr: true,
            port: 7001,
            cors: true,
            open: true,
            // 自定义代理规则
            proxy: {
                [env.VITE_APP_BASE_API]: {
                    target: 'http://47.93.153.78:8080', // 目标服务器的URL
                    changeOrigin: true,
                    rewrite: (path) => {
                        console.log('path-------------------------------------', path)
                        return path.replace(new RegExp(`^${env.VITE_APP_BASE_API}`), '')
                    },
                    bypass(req, res, options: any) {
                        const proxyURL = options.target + options.rewrite(req.url)
                        console.log('proxyURL', proxyURL)
                        req.headers['x-req-proxyURL'] = proxyURL // 设置未生效
                        res.setHeader('x-req-proxyURL', proxyURL) // 设置响应头可以看到
                    },
                },
            },
        },

        build: {
            // 处理清除console的插件
            minify: 'terser',
            terserOptions: {
                compress: {
                    drop_console: env.VITE_DELETE_CONSOLE === 'true',
                    drop_debugger: env.VITE_DELETE_CONSOLE === 'true',
                },
            },
        },
    })
}

这部分是env的配置

# 变量必须以VITE_为前缀才能暴露给外部获取
NODE_ENV = 'development'

VITE_SERVER_BASEURL = 'http://47.93.153.78:8080'
VITE_APP_BASE_API = '/dev-api'


# 是否去除console 和 debugger
VITE_DELETE_CONSOLE = false


这部分是request配置
import { useUserStore } from '@/store'
import type { UserInfo } from '@/typings'

// console.log('useUserStore:', useUserStore)

type Data<T> = {
    code: number
    msg: string
    data: T
}

// 请求基地址
export const baseUrl = import.meta.env.VITE_SERVER_BASEURL
export const baseUrlCors = import.meta.env.VITE_APP_BASE_API

// 拦截器配置
const httpInterceptor = {
    // 拦截器触发
    invoke(options: UniApp.RequestOptions) {
        const headers = options?.headers || {}
        const params = options?.params || {}
        // 1. 非http开头的请求地址需要拼接地址
        if (!options.url?.startsWith('http')) {
            options.url = baseUrl + baseUrlCors + options.url
        }

        // 携带参数
        if (Object.keys(params).length) {
            let carryParams = '?'
            Object.keys(params).forEach((item, index) => {
                carryParams += `&${item}=${params[item]}`
            })
            options.url += carryParams
        }
        // 2. 请求超时
        options.timeout = 10000 // 10s

        // 3. 添加小程序请求头标识
        options.header = {
            platform: 'mp-weixin', // 可选值与uniapp定义的平台一致, 告诉后台来源
            ...options.header,
        }

        // 4. 添加token请求头标识
        const userStore = useUserStore()
        const token = userStore.token
        if (token) {
            options.header.Authorization = `Bearer ${token}`
        }

        if (typeof headers.isToken === 'boolean' && !headers?.isToken) {
            delete options.header.Authorization
        }
    },
}

// 拦截request请求
uni.addInterceptor('request', httpInterceptor)

// 拦截uploadFile文件上传
uni.addInterceptor('uploadFile', httpInterceptor)

const http = <T>(options: UniApp.RequestOptions) => {
    // 返回Promise对象
    return new Promise<Data<T>>((resolve, reject) => {
        uni.request({
            ...options,
            // 响应成功
            success(res) {
                if ((res.data as Data<T>).code > 200 && res.statusCode === 200) {
                    uni.showToast({
                        icon: 'none',
                        title: (res.data as Data<T>).msg || '请求错误',
                    })
                    reject(res)
                }
                // 状态码 2xx 参考axios的设计
                else if (res.statusCode >= 200 && res.statusCode < 300) {
                    // 2.1 提取核心数据res.data
                    resolve(res.data as Data<T>)
                } else if (res.statusCode === 401) {
                    // 401错误 -> 清理用户信息, 跳转到登录页
                    const userStore = useUserStore()
                    userStore.logout()
                    uni.navigateTo({
                        url: '/pages/login/login',
                    })
                    setTimeout(() => {
                        uni.showToast({
                            icon: 'none',
                            title: '登陆过期',
                        })
                    })
                    reject(res)
                } else {
                    // 其他状态码 -> 根据后端错误信息轻提示
                    uni.showToast({
                        icon: 'none',
                        title: (res.data as Data<T>).msg || '请求错误',
                    })
                    reject(res)
                }
            },

            // 响应失败
            fail(err) {
                uni.showToast({
                    icon: 'none',
                    title: '网络错误, 换个网络试试',
                })

                reject(err)
            },
        })
    })
}

export default http


共有1个答案

仲孙善
2024-11-16

request请求 H5的时候 不要添加baseUrl
代理配置代理的是本地请求,你添加了baseUrl就不会被本地服务代理了

// 请求基地址
export const baseUrl = import.meta.env.VITE_SERVER_BASEURL  // H5的时候 赋值为''
export const baseUrlCors = import.meta.env.VITE_APP_BASE_API
 类似资料:
  • vite.config.js的代理配置失效 问题描述:一个前后端分离项目,前端为vue3+vite4项目, 我提供的后端接口为7002,url为http://localhost:7002/user/info 我在vite.config.js做了代理的配置,这个配置一直不生效, 实际请求路径一直是http://localhost:4000/user/info,一开始请求失败404,后来莫名其妙请求成

  • vite配置代理,target失效 配置的baseUrl 这是vite.config.js server的配置 调用请求后target指向前端地址http://localhost:3060,没有指向配置的后端target. 使用vite issues中的agent配置依旧无法解决[ [vite] http proxy error #8998](https://github.com/vitejs/v

  • 由vue-cli3.0创建的vue2.0项目 使用echarts制作3D 饼图时,在main.js中引ecarhts-gl后出现警告 ` import * as echarts from 'echarts' import 'echarts-gl' ` 这是为什么,如何解决这个警告 暂无

  • 鸿蒙arkts 请求失败了 mock 请求地址:https://dummyjson.com/quotes axios 发起请求 官网Http库

  • 有没有大佬知道ws://59.203.225.172:559/openUrl/OCr7PHi这种视频链接怎么播放,我使用jessibuca播放器播放视频发现没法播,websocket链接后,获取到的数据不是二进制的流 这是websocket链接后返回的数据

  • 配置HTTP成功,并且所有网页皆可访问。唯独HTTPS失败,我的nginx配置文件如下 访问情况 通过 openssl s_client -connect www.xiaoyangst.top:443 命令确保SSL和证书没有问题 后端Node.js服务正常启动,且通过PostMan工具测试后端没有问题。所以问题应该在nginx这边 我怀疑是没有把资源给到HTTPS,所以我把HTTP去掉,直接给到

  • 本文向大家介绍vue cli3 配置proxy代理无效的解决,包括了vue cli3 配置proxy代理无效的解决的使用技巧和注意事项,需要的朋友参考一下 vue cli3 创建的vue项目配置开发环境代理无效,网上的各种配置都试了,还是不行,最后终于试出来一种配置方法 vue.config.js配置如下内容(不要配置任何多余的选项,什么changOrigin pathRewrite 之类的东西都

  • 本文向大家介绍利用Nginx代理如何解决前端跨域问题详析,包括了利用Nginx代理如何解决前端跨域问题详析的使用技巧和注意事项,需要的朋友参考一下 前言 Nginx(发音同“engine X”)是异步框架的网页服务器,也可以用作反向代理、负载平衡器和HTTP缓存。 本文将讲述如何使用 Nginx 在 Web 前后端分离开发中实现路由的转发。 Web 开发通常使用的是前后端分离的开发模式,即前端和后