ReinerShir
V2EX  ›  Vue.js

后端初学 vue3+vite 快被这个打包+跨域问题烦死了!

  •  
  •   ReinerShir · Jul 10, 2024 · 14435 views
    This topic created in 846 days ago, the information mentioned may be changed or developed.

    问题是这样的:

    我使用了 vue3+vite 开发,vite 配置了代理如下:

    proxy: {
          '^/api*': {
            target: 'http://localhost:9961/',
            changeOrigin: true,
            // 替换掉/api 路径
            rewrite: (path) => path.replace(/^\/api/, ''),
          }
        }
    

    以上在本地开发时一切很美好,都正常,但是! 当打包成静态资源部署上服务器后恶心的就来了 vite 的代理失效了,访问路径变成了前端页面路径+/api/xxx ,查了一下这种情况需要使用 nginx 代理/api 路径,然后转发到后台服务。

    但是啊,我做的这个东西部署条件不支持装 nginx 啊,就不能直接访问后端接口吗?我后端接口都已经配置好了允许跨域,不管我是写死路径还是删除 vite 的 proxy 配置,最终打包后都会给我把请求路径替换成 /api/xxx

    我只想要直接请求后端接口为啥这么难?

    还有个让我很不解的地方,为啥用npm run preview一切都正常,我配好的后端接口地址也会正常请求,一旦放到服务器上就又变成了/api/xxx

    Supplement 1  ·  Jul 11, 2024
    本题可以终结了,之前之所以没成功是因为部署平台的问题,新的静态资源部署上去总是不生效,导致我以为是 vite 的问题

    现在我在本地使用 proxy ,请求地址用环境变量判断是走/api 还是直接请求后端接口来解决了
    72 replies  •  2025-06-12 14:02:45 +08:00
    Yishanshan
    Yishanshan
    Jul 10, 2024
    1
    你这个 proxy 只是本地的,线上不行,如果你不需要 api 的话,你可以在本地不加 api 的前缀
    loserc6
    loserc6
    Jul 10, 2024
    2
    接口地址与代理没关系,你看看你接口地址怎么写的吧
    linkopeneyes
    linkopeneyes
    Jul 10, 2024
    3
    不管是 dev 还是 preview 只是本地代理,你应该配个环境变量来区分你的开发环境和正式环境请求前缀
    zhtyytg
    zhtyytg
    Jul 10, 2024
    4
    proxy 本来就是开发服务器的代理
    ShiBuYi
    ShiBuYi
    Jul 10, 2024
    5
    不要开代理好了,服务端跨域直接放开
    ReinerShir
    ReinerShir
    OP
    Jul 10, 2024
    6
    @sjhhjx0122 配置了的,.env.production ,然后接口地址用的是变量,打包命令用的 npm run build --production
    但是不管我怎么折腾,部署上去后都变成了/api/xxx
    PeakGao666
    PeakGao666
    Jul 10, 2024
    7
    我有个好办法,直接让后端做一层 api 反代不就完了
    Vegetable
    Vegetable
    Jul 10, 2024
    8
    你发送请求的地方使用了相对地址,比如登录,你写的是 /login 。
    把这个地址改成绝对地址,比如 http://www.baidu.com/login ,这样打包出来的页面就会访问绝对地址了。

    接下来你会面临另一个问题,开发环境怎么办?如果你的所有环境都配置了 cors ,那你可以直接删除这个 proxy ,让页面直连服务器就可以了。你还需要通过通过 VITE_ENV 控制当前是什么环境,来访问不同的后端地址。

    进一步,你还要考虑怎么在打包期间传入生产地址,而不是写死在代码或者 vite.config 里边。建议找一个开源的管理后台项目学习一下他们的 http 部分代码。
    Elissa
    Elissa
    Jul 10, 2024
    9
    @ReinerShir
    1. proxy 代理只是本地的代理
    2. 本地运行时会通过 proxy 配置将接口地址中 api 替换成空的,打包后的和 proxy 代理就没关系了,不会替换字符串,也不会代理
    3. 线上总是出现/api/xxx ,检查下.env.production 中接口地址是不是包含了 api
    murmur
    murmur
    Jul 10, 2024
    10
    我们的后端接口都是全跨域支持,因为要给移动端用,移动端是虚拟的 http 服务器随机端口,没有域名这一说

    所以不代理也可以访问

    搞那么麻烦干嘛
    sseven
    sseven
    Jul 10, 2024
    11
    我感觉这个 proxy 的配置不是一个好的实践,api 开头,代理又要去掉 api ,那何必要写 api ?
    如果有些必须理由要 api 开头,用一个类似 baseUrl,commonPrefix 的东西,再通过环境变量来区分 build 和 dev 比较好控制
    Vegetable
    Vegetable
    Jul 10, 2024
    12
    没注意看,你还配置了 rewrite ,在后端无法配合你的情况下你不能这么做。你现在不得不从两个选项里选一个

    1. 后端网关处理/api
    2. 去掉代理,前端代码去掉/api
    sleepm
    sleepm
    Jul 10, 2024
    13
    不要打包(除非线上和开发环境没啥区别,包括环境变量,后端)
    在服务器 build
    访问路径写成和后端一样的
    代理是为了本地开发解决跨域,服务器上不需要解决跨域,就不需要配置代理
    zhhqiang
    zhhqiang
    Jul 10, 2024
    14
    request.js 文件 域名 打包的时候 指定成 你的服务端地址呢。
    BiChengfei
    BiChengfei
    Jul 10, 2024
    15
    桀桀桀,现在的前端是这样的
    xiaowunai
    xiaowunai
    Jul 10, 2024
    16
    vite 的代码,只是在开发环境的时候用 node 帮你转发了一次,跨域只是浏览器规则限制
    当你打包完了以后,就是一个前端项目,跨域你自然要用 nginx 什么的处理
    所以你以前真的是后端么?
    pelloz
    pelloz
    Jul 10, 2024❤️35
    17
    额,你真的是后端么...
    NoManPlay
    NoManPlay
    Jul 10, 2024
    18
    开发环境和生产环境通过环境变量配置区分就行了
    wyl986
    wyl986
    Jul 10, 2024 via iPhone
    19
    用 nginx 转发一下/api 到后端就完了,最简单最通用,不需要改任何代码
    zhhbstudio
    zhhbstudio
    Jul 10, 2024
    20
    我觉得这事有很大原因是 proxy 上层 key 从 devServe 改为 server 了。

    这个 proxy 配置只是给你开发时候方便调试用的。。。
    Xu3Xan89YsA7oP64
    Xu3Xan89YsA7oP64
    Jul 10, 2024
    21
    这是开发环境 vite 给你开的反向代理,解决跨域和路径问题。线上你没有反向代理的话,你需要先解决跨域问题,然后在后端处理 /api 啊,用中间件之类的把这个前缀去掉
    jones2000
    jones2000
    Jul 10, 2024
    22
    后台把跨域限制关掉呗
    CHTuring
    CHTuring
    Jul 10, 2024❤️1
    23
    你身为后端就应该明白,跨域和 Vite 这种打包器无关,甚至和前端无关。
    Vite 本地开发可以 proxy 完全是 Vite 方便开发人员而做的功能。
    你要做的是在把这些代码删掉,然后后端开启跨域白名单,或者配置 Ngnix
    microchang
    microchang
    Jul 10, 2024
    24
    。。。注意下项目里面,应该有个.env.production 文件,里面 VITE_API_URL = 怎么配的看一下
    shadowyue
    shadowyue
    Jul 10, 2024
    25
    哥你真是后端吗?跨域完完全全是需要后端来处理的。。。前端改不了一点,这是浏览器对 http 请求的安全规范。
    suyuyu
    suyuyu
    Jul 10, 2024
    26
    感觉你直接就不明白跨域
    suyuyu
    suyuyu
    Jul 10, 2024
    27
    看错了,抱歉,我自己打嘴 (
    KongLiu
    KongLiu
    Jul 10, 2024
    28
    CORS 了解一下
    Ritr
    Ritr
    Jul 10, 2024
    29
    production 环境变量没弄好
    1183460943
    1183460943
    Jul 10, 2024
    30
    本地代理就是给开发时候用的啊, 环境上要不用 nginx 搞个同样逻辑的代理,要不服务端开 CORS
    wisetc
    wisetc
    Jul 10, 2024 via iPhone
    31
    你的配置没错,不过那个只是 devsever ,可不是生产环境哦,打包得另求,而且前端调用后段 api 真的需要 proxy 吗,明白了,是为了设置 origin 吧,那么是不是前端代码那里写错了呢,proxy 配置是魔改,前端代码打包才是真实
    inc904
    inc904
    Jul 11, 2024
    32
    你可以把你的 两个环境的 env 文件 相关内容贴出来看下
    bsg1992
    bsg1992
    Jul 11, 2024
    33
    proxy 只用于开发环境啊 ,生成还是得指定 host 。 不指定 host 肯定用的当前部署的 host 作为请求地址啊
    cin
    cin
    Jul 11, 2024
    34
    配置个应用到 生产环境使用的 API_URL 变量, 或者打包时把前端输出到后端的 public 目录.
    jspatrick
    jspatrick
    Jul 11, 2024
    35
    如果你用的是 axios ,感觉你需要配置的是 baseURL ,通过环境变量切换不同的 baseURL
    xitler
    xitler
    Jul 11, 2024
    36
    你这个环境不支持 nginx 的话,那你打包出来的 dist 打算用啥东西访问
    NessajCN
    NessajCN
    Jul 11, 2024
    37
    你 po 一下后端接口我看看你怎么设置允许跨域的
    xR13zp0h67njQr2S
    xR13zp0h67njQr2S
    Jul 11, 2024❤️1
    38
    @sseven nginx 为什么要有 rewrite ,不是因为后端所有的开头地址没有 api ,然后去除的吗?为什么写 api 开头,因为不写 api 开头你知道什么是页面,什么是请求吗
    unco020511
    unco020511
    Jul 11, 2024
    39
    我们现在都是代码里直接用线上域名,然后开发机器上通过代理工具(比如 whistls)来处理跨域和环境区分,代码无需任何区分
    shunia
    shunia
    Jul 11, 2024
    40
    不是,你到底有没有代码控制权啊,给我整蒙了。。。
    如果实在不能改代码,那我能理解这是咋回事,不然好像有点。。。

    前端非要请求/api 下的接口?后端非不提供/api 的接口?
    unco020511
    unco020511
    Jul 11, 2024
    41
    说实话作为一个前端新人,我一直也每没明白这个 proxy 配置是怎么个配置,经常看到先加一个 api,然后又 rewrite 去掉 api,不太理解
    xR13zp0h67njQr2S
    xR13zp0h67njQr2S
    Jul 11, 2024
    42
    @unco020511 #41 加 api 是本地开发的时候用来做请求代理,让访问 api 的请求自己不处理,都走代理,rewrite 掉 api 是因为后端的接口地址没有 api ,如果后端有地址有 api 比如用 tomcat 启动的这种,加上 api 就可以删除 rewrite
    TimPeake
    TimPeake
    Jul 11, 2024
    43
    摒除跨域/前端本地开发代理方便等原因 ,api 前缀相关问题,出现这个问题的根本原因是因为你的后端项目接口没有统一的路由前缀,有统一的前缀,你这个问题就好理解了。
    unco020511
    unco020511
    Jul 11, 2024
    44
    @78786381 #42 那么在实际发起接口请求时,是用带域名的全路径还是相对路径?发起请求时,域名需要区分环境吗
    5200
    5200
    Jul 11, 2024
    45
    你这个问题问的,让前端和后端都看懵了😂
    Marthemis
    Marthemis
    Jul 11, 2024
    46
    1.为什么要加上/api ,而又去掉/api
    kyznever
    kyznever
    Jul 11, 2024
    47
    后端搞个 CORS 。还要啥代理啊
    Marthemis
    Marthemis
    Jul 11, 2024
    48
    1.为什么要加上/api ,而又去掉/api
    是因为前端想在开发时去代理全部的 api 接口而不去代理静态资源等请求(其实这里用 /proxy 前缀更合适)但是后端的接口一般不带前缀。
    2.如何避免后端配合前端改动,例如要求后端接口统一加上 /api 前缀
    可以在前端的请求库例如 axios 配置一个 baseURL,写上 process.env.node_env === 'development' ? '/api' : '/'(或者后端接口部署的服务器域名)
    Marthemis
    Marthemis
    Jul 11, 2024
    49
    至于为什么会发展出这些前端代理,是因为以前有很多后端(特指水平差的)不懂跨域也不愿意帮助去解决跨域...
    JayZXu
    JayZXu
    Jul 11, 2024
    50
    静态资源托管的地方都能配置反向代理:无论是传统的 nginx ,Apache 或者后端服务都能做到
    Marthemis
    Marthemis
    Jul 11, 2024
    51
    当然了,你这里的情况一定是接口 url 前配置了/api (直接或者间接)。开发环境被 rewrite 了而生产环境没有。可以根据这个思路去找一下各个配置文件或者代码文件
    xR13zp0h67njQr2S
    xR13zp0h67njQr2S
    Jul 11, 2024
    52
    @unco020511 #44 都可以,看运维和你们前后端安排,都可以完成这个工作
    MoonWalker
    MoonWalker
    Jul 11, 2024❤️1
    53
    说句不爱听的....跟后端初学不初学的无关
    Torpedo
    Torpedo
    Jul 11, 2024
    54
    @pelloz #17 在某些规模不小的厂,很多后端配跨域头都搞不定的。合作过的至少有 2 、30 不行
    GOURIDE
    GOURIDE
    Jul 11, 2024❤️1
    55
    后端不是有拦截器过滤器么,直接改响应头跟 nginx 效果一个样。问题很小白
    AV1
    AV1
    Jul 11, 2024 via Android
    56
    vite 里的“代理”,是给 coding 时候用的,又不是给你打包上生产的时候用的。
    你打包之后,它肯定管不了你配置的那些东西了。
    sgiyy
    sgiyy
    Jul 11, 2024
    57
    这个提问,能感觉你对后端也不是很懂
    hm20062006ok
    hm20062006ok
    Jul 11, 2024
    58
    临时办法是: "在本地开发时一切很美好" , 保持现有不要改动。 打包正式环境时: 请求库用的 Axio 吧? 把 baseURL 写死成 https://example.com/xxxx. 比如 login 接口完整的地址是:https://example.com/api/login ,login 方法传递的 path 是‘’/login', 那么 baseURL 就填写:https://example.com/api 。 打包完再把 baseURL 改回来。 改来改去很麻烦? 你再去研究为什么要配置 env 吧
    zhw2590582
    zhw2590582
    Jul 11, 2024
    59
    既然这样,建议开发阶段不要使用 proxy ,统一让后端配置跨域
    abcde123456789
    abcde123456789
    Jul 11, 2024
    60
    如果后端允许跨域,就不需要设置 proxy ,开发环境和正式环境都不需要

    后端允许跨域和 proxy 只存在一个就行了,都有的话会出错
    gp0119
    gp0119
    Jul 11, 2024
    61
    你的接口是不需要 /api 前缀的?在 axios 配置文件 baseURL 里去掉 /api, 在 proxy 配置文件 target 里路径后面加上 api ,估计测试环境里刚好把你 baseURL 里 /api 前缀替换掉了
    ColdBird
    ColdBird
    Jul 11, 2024
    62
    你后端允许跨域,那就配置网络请求的全路径不要用资源域名就得了呗,这点东西搞不明白吗?大部分后端接口不允许跨域,所以才需要访问资源域名,在资源域名通过 nginx 配置代理。
    dumbass
    dumbass
    Jul 11, 2024
    63
    @unco020511 #40
    我一般都是在 .env 文件里配置一个 VITE_APP_HOST ,
    本地开发 .env.development 里 VITE_APP_HOST=/api
    正式环境的 .env.production VITE_APP_HOST=正式环境接口地址
    然后在 axios 里 axios.defaults.baseURL = import.meta.env.VITE_APP_API_HOST ,vite 配置按照楼主写的,target 设置为测试环境接口地址
    这样请求的时候本地开发请求 /api 会被 vite 代理到测试环境下而没有跨域问题。打包部署到线上请求的就是正式环境接口,更不会有跨域问题。
    dumbass
    dumbass
    Jul 11, 2024
    64
    @bojackhorseman axios.defaults.baseURL = import.meta.env.VITE_APP_HOST ,手误
    sseven
    sseven
    Jul 11, 2024
    65
    @78786381 #38 我意思是:用的地方 request('a/c'),别带 api ,request 中统一加 api 前缀。这样方便控制前缀。而不要在代码中写 request('api/a/c'). 大概率是个单页应用,是不是就不用区分页面还是请求
    xR13zp0h67njQr2S
    xR13zp0h67njQr2S
    Jul 11, 2024
    66
    @sseven #65 那我估计你的理解还是错误的,proxy 那里设置 api 开头本来就是做区分的,是 node 处理还是代理,肯定不会每一个地方都写 api
    4Et5ShxMIq58n6Lr
    4Et5ShxMIq58n6Lr
    Jul 11, 2024
    67
    我知道为啥有人发了帖子说 跨域问题了
    shengchao
    shengchao
    Jul 11, 2024
    68
    作为前端,我很难理解后端对此有什么困惑的?
    monologue520
    monologue520
    Jul 11, 2024
    69
    按照你的思路解决这个问题需要使用环境变量,在前端加 baseURL 的地方通过变量做下判断就可以了
    kanepan19
    kanepan19
    Jul 11, 2024
    70
    0xD800
    0xD800
    Jul 12, 2024
    71
    你是给 axios 配置了 baseUrl='/api'吧,
    我建议你了解基本的技术原理。
    1. vue-router 的 history 模式,如果你是部署在后端应用中,比如放在 springboot 的 static 文件夹内,建议你直接设置为 webhashhistory ,否则你要手动处理路由,我觉得你可能会花费更多时间

    2. vite 的 build.base ,这个是打包的时候把里面的引用文件都加上这个前缀,应用场景:把前端部署在某个域名的/xx 文件夹下,通过 www.example.com/xx/index.html 访问,此时也要主要 vue-router 的 history 的 base 参数

    3. axios 的 baseUrl:这个是 API 接口的前缀,你可以控制在本地环境使用/api 前缀,然后用 proxy 拦截/api 前缀再转发。生产环境配置其他的 baseUrl 或者不配,看你后端地址怎么访问
    skkakaka2
    skkakaka2
    Jun 12, 2025
    72
    什么叫没有条件安装 nginx ?没有 nginx 你的前端是怎么跑起来的?
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1818 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 113ms · UTC 16:59 · PVG 00:59 · LAX 08:59 · JFK 11:59
    ♥ Do have faith in what you're doing.