Go-vue 前后端跨域 (cors+axios)

    技术2022-07-10  173

    Gin-vue 跨域

    vue

    安装
    npm install axios --save
    在main.js中引入axios插件 ,并设置axios全局配置
    import Axios from 'axios' Vue.prototype.$axios = Axios Axios.defaults.baseURL = 'http://localhost:9090' Axios.defaults.headers.post['Content-Type'] = 'applicaation/json'
    config文件夹中的index.js中添加代理配置
    proxyTable: { '/': { target: 'http://localhost:9090', // gin访问地址 changeOrigin: true, //送请求头中host会设置成target } }
    .vue文件使用axios
    get请求: this.$axios.get('/user/getAll') .then(res => { console.log(res) }) } post请求(设置了请求参数为form格式) this.$axios.post('/user/addCoins', qs.stringify({ uid: this.uid, coins: this.coins }), { headers: {'Content-Type': 'application/x-www-form-urlencoded'} }) .then(res => { console.log(res) }) .catch(err => { console.log(err) })

    axios默认的Content-type是application/json;charset=UTF-8, vue传参form-data格式时需要使用qs,并在hearders中设置 引入import qs from ‘qs’ ,

    gin

    路由中使用cors方法 router.Use(Cors())

    func Cors() gin.HandlerFunc { return func(c *gin.Context) { method := c.Request.Method // 接受指定域的请求,可以使用*不加以限制,但不安全 c.Header("Access-Control-Allow-Origin", "127.0.0.1") //请求的允许的头字段与权限控制 c.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization, Token") //请求类型 c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS") c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type") //是否允许后续请求携带认证信息,该值只能是true,否则不返回 c.Header("Access-Control-Allow-Credentials", "true") // 放行所有OPTIONS方法 if method == "OPTIONS" { c.AbortWithStatus(http.StatusNoContent) } c.Next() } }

    使用cors,跨域请求时,按照http协议标准,对于一些请求,前端要先发一次options请求验证,验证通过再发真正的请求。

    Axios拦截器

    可以设置请求拦截和响应拦截,在发出请求和响应到达then处理之前进行操作,用来实现在请求头中加入Authorization

    Axios.interceptors.request.use( res => { if (localStorage.getItem('Authorization')) { res.headers.Authorization = localStorage.getItem('Authorization') } return res }, err => { return Promise.reject(err) //对象的拒绝状态,返回错误信息 })

    localStorage生命周期是永久,将第一次请求的数据直接存储到本地,内存空间比cookie大,可以在登录时使用存储插件vuex和mapMutations映射方法储存接口所返回的token 示例: 创建文件夹store,建立文件index.js ,在main.js中引入srore

    import Vuex from 'vuex' Vue.use(Vuex) const store = new Vuex.Store({ state: { // 读取token Authorization: localStorage.getItem('Authorization') ? localStorage.getItem('Authorization') : '', }, mutations: { // 修改token,并将token存入localStorage changeLogin (state, user) { state.Authorization = user.Authorization localStorage.setItem('Authorization', user.Authorization) }, } }) export default store

    在login.vue中使用

    import { mapMutations } from 'vuex'

    Method方法内

    ...mapMutations(['changeLogin']), //映射到changeLogin方法上 this.changeLogin({ Authorization: res.data.token }) // 存储请求接口返回的token

    我在这里还遇到了一个报错 开始以为所使用的文件或方法位置不对,或是所使用的映射方法 …mapMutations的问题,但修改多次还是同样的报错。

    问题原因:在token这里 SyntaxError: Unexpected token 也就是不支持…的方法

    解决方法:npm install --save-dev babel-plugin-transform-object-rest-spread .babelrc配置文件内添加 “plugins”: [ [“transform-object-rest-spread”] ]

    Processed: 0.016, SQL: 9