Enjoy your life

AEnjoy’s Blog

解决前端Vue3+vite+axios+cookie跨域报错问题 后端Go+gin

自己在写一个项目,目前遇到了问题:前端需要向后端执行ajax请求获取数据,需要传递cookie。如果使用默认的代码不进行配置则会出现跨域问题cors报错,本文将解决问题.

前端(node.js+Vite):http://localhost:5173

后端(golang + gin):http://localhost:8088/

问题出现

前端需要向后端请求数据/api/devices/snlspjrnzxcevyfk/info,后端通过前端传递过来的cookie进行身份识别,授权成功返回200,JSON数据, 失败返回401未授权或404.

当我们使用默认参数不做配置时,直接请求会被拦截,进而无法获取数据。参考网上的教程在解决请求跨域后,又少有解决cookie传递的,参考几篇资料后,结合本人项目,目前问题已解决。

cookie:IOMAuth

解决措施

前端部分

vite.config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
export default defineConfig({
plugins: [
vue(),
AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
},
server: {
host: '0.0.0.0',
//port: 8088,
proxy: {
'/api': {
// 后台地址
target: 'http://localhost:8088/',
changeOrigin: true,
secure: false,
ws: true,
followRedirects: true, //cookie自动跳转传递
rewrite: path => path.replace(/^\/api/, ''),
onProxyReq(proxyReq, req, res) {
originHost = req.headers['x-forwarded-for']
const cookie = req.headers['cookie']
if (cookie) {
proxyReq.setHeader('cookie', cookie)
}
},
onProxyRes(proxyRes, req, res) {
if (proxyRes.headers['set-cookie']) {
// cookie 传递重点
proxyRes.headers['Access-Control-Allow-Credentials'] = 'true';
}
}

},
}
},
})

axios配置 axiosInstance.js

1
2
3
4
5
6
7
8
9
10
11
import axios from 'axios'

axios.defaults.withCredentials = true; //重点

const API = axios.create({
baseURL:'http://localhost:8088',
timeout: 2000,
withCredentials:true //重点 这参数可以放上边,也可以放里面
})

export default API

后端

go gin路由设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
func RouterInit() {
global.Router = gin.Default()
global.Router.Use(func(c *gin.Context) {
method := c.Request.Method
origin := c.Request.Header.Get("Origin") //请求头部
if origin != "" {
//接收客户端发送的origin (重要!)
//Access-Control-Allow-Origin是必须的,他的值要么是请求Origin字段的值,要么是一个*, 表示接受任意域名的请求
c.Writer.Header().Set("Access-Control-Allow-Origin", origin) //设置为*会报错
//服务器支持的所有跨域请求的方法
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE,UPDATE")
//允许跨域设置可以返回其他子段,可以自定义字段
//该字段可选。CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。
//如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。上面的例子指定,getResponseHeader('FooBar')可以返回FooBar字段的值。
c.Header("Access-Control-Allow-Headers", "Authorization, Content-Length, X-CSRF-Token, Token, session, IOMAuth")
// 允许浏览器(客户端)可以解析的头部 (重要)
c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers")
//设置缓存时间
//该字段可选,用来指定本次预检请求的有效期,单位为秒。有效期是20天(1728000秒),即允许缓存该条回应1728000秒(即20天),在此期间,不用发出另一条预检请求。
c.Header("Access-Control-Max-Age", "172800")
//允许客户端传递校验信息比如 cookie (重要)
c.Header("Access-Control-Allow-Credentials", "true")
}
//允许类型校验
if method == "OPTIONS" {
c.JSON(http.StatusOK, "ok!")
}

defer func() {
if err := recover(); err != nil {
logrus.Panic("Panic info is: %v", err)
}
}()
c.Next()
})
regRouter()
global.Router.Run(":" + global.WebPort)
}