V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Zhouisme
V2EX  ›  程序员

[请教]Vue3+Vite 跨域问题,自己找不出原因

  •  
  •   Zhouisme · 164 天前 · 1881 次点击
    这是一个创建于 164 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在学 Vue,遇到跨域问题,希望大家帮忙解决,看看问题出在哪里?

    post query 请求地址: https://manga.bilibili.com/twirp/comic.v1.Comic/Banner?device=pc&platform=web 在 vite.config.js 中配置如下。

      server: {
        proxy: {
          '/api': {
            target: 'https://manga.bilibili.com',
            changeOrigin: true,  // 允许跨域
            rewrite: (path) => path.replace(/^\/api/, ''),
          }
        }
      }
    

    在 xx.vue 中代码

    axios.post('/api/twirp/comic.v1.Comic/Banner', {}, {
        params: {
            device: 'pc',
            platform: 'web',
        }
    }).then((res) => {
        console.log('res: ', res)
    })
    

    报错如下: 这里是 400

    xhr.js:220          POST http://127.0.0.1:5173/api/twirp/comic.v1.Comic/Banner?device=pc&platform=web 400 (Bad Request)
    
    127.0.0.1/:1 Uncaught (in promise) AxiosError {message: 'Request failed with status code 400', name: 'AxiosError', code: 'ERR_BAD_REQUEST', config: {…}, request: XMLHttpRequest, …}
    

    (没办法这么试了下) 如果axios.post('/api/twirp/comic.v1.Comic/Banner', {}, {改为axios.post('/twirp/comic.v1.Comic/Banner', {}, { 就是 404 (Not Found)

    请大佬瞧瞧,困扰了我两三个小时了,别的地址的 get 请求出跨域问题,这样配置跨域第一种方法可以正常解决。

    第 1 条附言  ·  164 天前

    疑似b站的问题。好奇postman可以请求,axios就不可以...

    我人傻了

    验证方式:本地自己搭一个web api post query

    • web server
    package main
    
    import (
    	"fmt"
    
    	"github.com/gin-gonic/gin"
    )
    
    func main() {
    	router := gin.Default()
    
    	router.POST("/demo", func(ctx *gin.Context) {
    		id := ctx.Query("id")
    		fmt.Println(id)
    
    		ctx.JSON(200, gin.H{
    			"id": id,
    		})
    	})
    	router.Run()
    }
    
    
    axios({
        url: 'api/demo',
        method: 'POST',
        params: {
            id: 1
        }
        // data: {
        //     device: 'pc',
        //     platform: 'web',
        // }
    }).then((res) => {
        console.log('res: ', res.data)
    })
    
    // 如果不加vite配置,也是存在跨站问题
    
      server: {
        proxy: {
          '/api': {
            target: 'http://127.0.0.1:8080',
            changeOrigin: true,  // 允许跨域
            rewrite: (path) => path.replace(/^\/api/, ''),
          }
        }
      }
    

    // 正常返回 res: {id: '1'}

    24 条回复    2022-08-26 21:57:26 +08:00
    yhappy
        1
    yhappy  
       164 天前
    跨域看起来没问题,建议检查一下请求带的数据格式对着上吗?先用 Postman 试一下
    Zhouisme
        2
    Zhouisme  
    OP
       164 天前
    @yhappy params:{}里的数据没有问题,都是对得上的。
    westoy
        3
    westoy  
       164 天前 via Android
    B 站的 API 有针对一些 header 头做判断,纯 GET 的在新页面打开都直接禁止的,必须要传全。
    Zhouisme
        4
    Zhouisme  
    OP
       164 天前
    @westoy 这个地址我在 postman 类型的工具上是可以正常获取 json 的。马上尝试一下是不是 b 站的问题。
    tramm
        5
    tramm  
       164 天前
    只有浏览器有跨域问题啊, PostMan 肯定没问题的哇
    shakukansp
        6
    shakukansp  
       164 天前
    rewrite: (path) => path.replace(/^\/api/, '')
    =>
    rewrite: (path) => path.replace(/^\/api, '')
    shakukansp
        7
    shakukansp  
       164 天前
    @shakukansp 看错了,对的
    Geo200
        8
    Geo200  
       164 天前
    服务端没有开放跨域限制浏览器端怎么整活都百搭,跟 postman 不是一个原理
    kanezeng
        9
    kanezeng  
       164 天前
    跨域的问题主要是:
    1 、浏览器里才会有,Postman 以及其它工具肯定不会有。
    2 、处理需要后端服务去做,前端就不要折腾了。
    darrenfang
        10
    darrenfang  
       164 天前
    这报的不是 400 Bad Request 吗?

    试试这样:

    axios.post('/api/twirp/comic.v1.Comic/Banner', {
    device: 'pc',
    platform: 'web'
    }).then((res) => {
    console.log('res: ', res)
    })
    shakukansp
        11
    shakukansp  
       164 天前
    本地试了下
    server: {
    proxy: {
    '/api/': {
    target: 'https://manga.bilibili.com/',
    changeOrigin: true,
    headers: {
    origin: 'https://manga.bilibili.com',
    },
    rewrite: (path) => path.replace(/^\/api/, ''),
    },
    },
    },
    要加个 origin
    这样可以
    话说报 400 你不看下时睡眠错误吗
    我看到 400 的错误就是 origin invalid
    这不提示的很清楚吗
    smd
        12
    smd  
       164 天前
    axios 有个 baseURL ,看下是不是那里的问题
    lingxiaoli
        13
    lingxiaoli  
       164 天前
    post 的参数字段是 data get 的参数字段是 parmas
    micean
        14
    micean  
       164 天前
    跨域属于浏览器安全策略,浏览器会因本地与服务器的 host+port 不一致发起 OPTIONS 请求到服务器,由服务器判断返回是否可以跨域。
    具体可以打开 chrome 控制台看 netword 的 other 一栏
    zhuweiyou
        15
    zhuweiyou  
       164 天前
    报错 400 跟跨域有什么关系? 要么参数 要么 header 没传全
    lisongeee
        16
    lisongeee  
       164 天前
    这样可以正常返回 200 状态码和正常的数据

    ```ts
    import { defineConfig } from 'vite';

    export default defineConfig(({ command }) => {
    return {
    server: {
    proxy: {
    '^/api': {
    target: 'https://manga.bilibili.com',
    changeOrigin: true,
    rewrite: (path) => path.replace(/^\/api/, ''),
    headers: {
    origin: 'https://manga.bilibili.com',
    },
    },
    },
    },
    };
    });
    ```

    另外说一下,这不是跨域,这是**反向代理**

    因为从浏览器的角度看,你只是向本域名的 /api/xxx 发起了一个 post 请求,根本没有产生两个域的概念
    feeeff
        17
    feeeff  
       164 天前
    请教大家一个问题

    > 跨域属于浏览器安全策略

    既然出现跨域的原因是保护浏览器安全,为什么反而在服务端进行设置是否可以跨域。

    试想一个场景,假设我是提供「危险接口」的接口提供者,肯定希望越多浏览器使用我的接口越好,那么为什么还会在服务端进行是否可以跨域设置呢?
    micean
        18
    micean  
       164 天前
    @feeeff

    不是这个场景。比如你做了一个伪 V2EX ,直接跨域调用 V2EX 的 api ,盗取用户信息,这个成本是很低的
    Zhouisme
        19
    Zhouisme  
    OP
       164 天前
    @shakukansp 十分感谢你的帮助,解决了我的问题。添加 headers:{}字段果然就正常请求了。因为是萌新,有些内容还不了解。
    Zhouisme
        20
    Zhouisme  
    OP
       164 天前
    @lingxiaoli 不行,axios#post(url[, data[, config]])的第二个参数是请求体。消息头也是错误的:‘http://127.0.0.1:5173/api/twirp/comic.v1.Comic/Banner’,不会携带参数。
    Zhouisme
        21
    Zhouisme  
    OP
       164 天前
    @zhuweiyou 是的,调试的时候出现过 CORS 问题,也有 400 问题,知道 400 是 bad request,但不知道如何解决。添加 header 就行。
    Zhouisme
        22
    Zhouisme  
    OP
       164 天前
    @lisongeee 可以解决问题。受教了。出现 400 的确不是跨域问题,只是当事一并出现,误以为如此。
    LancerComet
        23
    LancerComet  
       164 天前
    嗨呀,那个 400 就不是跨域问题,跨域的话你连 400 的返回都是拿不到的
    Zhouisme
        24
    Zhouisme  
    OP
       163 天前
    @LancerComet 欧吼,我晓得了 :)
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   实用小工具   ·   3663 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 40ms · UTC 10:36 · PVG 18:36 · LAX 02:36 · JFK 05:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.