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

2022-08-26 01:43:51 +08:00
 Zhouisme

在学 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 请求出跨域问题,这样配置跨域第一种方法可以正常解决。

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

试试这样:

axios.post('/api/twirp/comic.v1.Comic/Banner', {
device: 'pc',
platform: 'web'
}).then((res) => {
console.log('res: ', res)
})
shakukansp
2022-08-26 09:12:36 +08:00
本地试了下
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
2022-08-26 09:15:01 +08:00
axios 有个 baseURL ,看下是不是那里的问题
lingxiaoli
2022-08-26 09:25:58 +08:00
post 的参数字段是 data get 的参数字段是 parmas
micean
2022-08-26 09:33:40 +08:00
跨域属于浏览器安全策略,浏览器会因本地与服务器的 host+port 不一致发起 OPTIONS 请求到服务器,由服务器判断返回是否可以跨域。
具体可以打开 chrome 控制台看 netword 的 other 一栏
zhuweiyou
2022-08-26 09:38:41 +08:00
报错 400 跟跨域有什么关系? 要么参数 要么 header 没传全
lisongeee
2022-08-26 10:13:06 +08:00
这样可以正常返回 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
2022-08-26 10:13:42 +08:00
请教大家一个问题

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

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

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

不是这个场景。比如你做了一个伪 V2EX ,直接跨域调用 V2EX 的 api ,盗取用户信息,这个成本是很低的
Zhouisme
2022-08-26 12:51:50 +08:00
@shakukansp 十分感谢你的帮助,解决了我的问题。添加 headers:{}字段果然就正常请求了。因为是萌新,有些内容还不了解。
Zhouisme
2022-08-26 12:57:36 +08:00
@lingxiaoli 不行,axios#post(url[, data[, config]])的第二个参数是请求体。消息头也是错误的:‘http://127.0.0.1:5173/api/twirp/comic.v1.Comic/Banner’,不会携带参数。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/875475

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX