在学 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 请求出跨域问题,这样配置跨域第一种方法可以正常解决。
疑似b站的问题。好奇postman可以请求,axios就不可以...
我人傻了
验证方式:本地自己搭一个web api post query
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'}
|      1yhappy      2022-08-26 02:04:36 +08:00 跨域看起来没问题,建议检查一下请求带的数据格式对着上吗?先用 Postman 试一下 | 
|  |      3westoy      2022-08-26 02:29:36 +08:00 via Android B 站的 API 有针对一些 header 头做判断,纯 GET 的在新页面打开都直接禁止的,必须要传全。 | 
|      4Zhouisme OP @westoy 这个地址我在 postman 类型的工具上是可以正常获取 json 的。马上尝试一下是不是 b 站的问题。 | 
|  |      5tramm      2022-08-26 08:48:08 +08:00 只有浏览器有跨域问题啊, PostMan 肯定没问题的哇 | 
|  |      6shakukansp      2022-08-26 08:48:29 +08:00 rewrite: (path) => path.replace(/^\/api/, '') => rewrite: (path) => path.replace(/^\/api, '') | 
|  |      7shakukansp      2022-08-26 08:51:15 +08:00 @shakukansp 看错了,对的 | 
|      8Geo200      2022-08-26 08:54:08 +08:00 服务端没有开放跨域限制浏览器端怎么整活都百搭,跟 postman 不是一个原理 | 
|  |      9kanezeng      2022-08-26 08:58:32 +08:00 跨域的问题主要是: 1 、浏览器里才会有,Postman 以及其它工具肯定不会有。 2 、处理需要后端服务去做,前端就不要折腾了。 | 
|      10darrenfang      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) }) | 
|  |      11shakukansp      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 这不提示的很清楚吗 | 
|  |      12smd      2022-08-26 09:15:01 +08:00 axios 有个 baseURL ,看下是不是那里的问题 | 
|  |      13lingxiaoli      2022-08-26 09:25:58 +08:00 post 的参数字段是 data  get 的参数字段是 parmas | 
|      14micean      2022-08-26 09:33:40 +08:00 跨域属于浏览器安全策略,浏览器会因本地与服务器的 host+port 不一致发起 OPTIONS 请求到服务器,由服务器判断返回是否可以跨域。 具体可以打开 chrome 控制台看 netword 的 other 一栏 | 
|      15zhuweiyou      2022-08-26 09:38:41 +08:00 报错 400 跟跨域有什么关系? 要么参数 要么 header 没传全 | 
|  |      16lisongeee      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 请求,根本没有产生两个域的概念 | 
|      17feeeff      2022-08-26 10:13:42 +08:00 请教大家一个问题 > 跨域属于浏览器安全策略 既然出现跨域的原因是保护浏览器安全,为什么反而在服务端进行设置是否可以跨域。 试想一个场景,假设我是提供「危险接口」的接口提供者,肯定希望越多浏览器使用我的接口越好,那么为什么还会在服务端进行是否可以跨域设置呢? | 
|      18micean      2022-08-26 10:54:44 +08:00 | 
|      19Zhouisme OP @shakukansp 十分感谢你的帮助,解决了我的问题。添加 headers:{}字段果然就正常请求了。因为是萌新,有些内容还不了解。 | 
|      20Zhouisme OP @lingxiaoli  不行,axios#post(url[, data[, config]])的第二个参数是请求体。消息头也是错误的:‘http://127.0.0.1:5173/api/twirp/comic.v1.Comic/Banner’,不会携带参数。 | 
|      21Zhouisme OP @zhuweiyou 是的,调试的时候出现过 CORS 问题,也有 400 问题,知道 400 是 bad request,但不知道如何解决。添加 header 就行。 | 
|  |      23LancerComet      2022-08-26 14:20:21 +08:00 嗨呀,那个 400 就不是跨域问题,跨域的话你连 400 的返回都是拿不到的 | 
|      24Zhouisme OP @LancerComet 欧吼,我晓得了 :) |