美文网首页前端Vuevue2.0大全
Vue 进阶教程之:Axios配置JWT/封装插件/发送表单数据

Vue 进阶教程之:Axios配置JWT/封装插件/发送表单数据

作者: Yi罐可乐 | 来源:发表于2017-07-03 10:24 被阅读5574次

    尤雨溪之前在微博发布消息,不再继续维护 vue-resource,并推荐大家开始使用 Axios,本文就说一下在 Vue 项目里使用 Axios 配置 JWT 、全局拦截请求、发送表单数据等等。

    本文里使用的示例代码,已测试能正常使用

    首先请务必已仔细阅读 Axios 文档并熟悉 JWT:

    安装

    npm i axios 
    npm i es6-promise 
    

    为什么要安装 promise polyfill ?虽然 Axios 的 GitHub 主页开头说了支持 IE8,但文档最下面又「偷偷」说,前提是浏览器支持 promise (太鸡贼了),如果你不用关心浏览器兼容,那就不用安装 es6-promise (那你也太幸福了)。

    把 Axios 配置成 Vue 插件

    用过 vue-resource 的都知道,它本身封装成了 Vue 插件,可以直接在 Vue 组件里使用 this.$http, Axios 本身虽然没有封装,但我们也可以手动把它封装成 Vue 插件。
    具体原理请看 Vue框架引入JS库的正确姿势,下面我就用代码演示一下:

    AxiosPlugin.js

    require('es6-promise').polyfill() // 引入一次就行
    import axios from 'axios'
    
    // 创建 axios 实例
    // 这里 export  的原因是方便组件外使用 axios
    export const Axios = axios.create({
      baseURL: 'xxx', 
      timeout: 5000,
    })
    
    // 将 Axios 实例添加到Vue的原型对象上
    export default {
      install(Vue) {
        Object.defineProperty(Vue.prototype, '$http', { value: Axios })
      }
    }
    

    main.js

    import Vue from 'vue'
    import AxiosPlugin from 'xxx/xxx/AxiosPlugin'
    Vue.use(AxiosPlugin)
    

    使用 axios 示例

    在组件内部↓↓

    // GET 获取用户信息
    // http://xxxx/user?a=1&b=2
    const data = {
      params: {
        a: 1,
        b: 2,
      }
    }
    this.$http.get(url, data).then(res => {
      console.log(res)
    })
    
    // POST  请求
    const data = {
      a: 1,
      b: 2,
    }
    this.$http.post(url, data).then(res => {
      console.log(res)
    })
    
    

    在组件外部↓↓

    // POST
    import { Axios } from 'xxx/xxx/AxiosPlugin'
    Axios.post(url, data)
    

    以上是 Axios 的基本配置,下面我们说一下如何以 x-www-form-urlencoded 格式发送表单数据、设置 JWT 的 token 、以及 token 过期自动登录。

    高级配置

    废话不多说,直接上完整的代码,伸手党的福利
    AxiosPlugin.js

    require('es6-promise').polyfill()
    import axios from 'axios'
    
    export const Axios = axios.create({
      baseURL:  'http://xxxxx/',
      timeout: 10000,
    })
    
    //POST传参序列化(添加请求拦截器)
     // 在发送请求之前做某件事
    Axios.interceptors.request.use(config => {
        // 设置以 form 表单的形式提交参数,如果以 JSON 的形式提交表单,可忽略
        if(config.method  === 'post'){
            // JSON 转换为 FormData
            const formData = new FormData()
            Object.keys(config.data).forEach(key => formData.append(key, config.data[key]))
            config.data = formData
        }
    
        // 下面会说在什么时候存储 token
        if (localStorage.token) {   
            config.headers.Authorization = 'JWT ' + localStorage.token
        }
        return config
    },error =>{
        alert("错误的传参", 'fail')
        return Promise.reject(error)
    })
    
    //返回状态判断(添加响应拦截器)
    Axios.interceptors.response.use(res =>{
       //对响应数据做些事
        if(!res.data.success){
           alert(res.error_msg)
           return Promise.reject(res)
        }
        return res
    }, error => {
        if(error.response.status === 401) {
          // 401 说明 token 验证失败
          // 可以直接跳转到登录页面,重新登录获取 token
          location.href = '/login'
        } else if (error.response.status === 500) {
           // 服务器错误
           // do something
           return Promise.reject(error.response.data)
        }
        // 返回 response 里的错误信息
        return Promise.reject(error.response.data)
    })
    
    export default {
      install(Vue) {
        Object.defineProperty(Vue.prototype, '$http', { value: Axios })
      }
    }
    

    main.js

    import Vue from 'vue'
    import AxiosPlugin from 'xxx/xxx/AxiosPlugin'
    Vue.use(AxiosPlugin)
    

    Login.vue ↓

    export default {
      name: 'Login',
      data() {
        return {
          username: '',
          password: '',
        }
      },
      methods: {
        onLogin() {
          const { username, password } = this
          const data = {
            username,
            password
          }
    
          this.$http.post('url', data)
            .then(res => {
             // 登录成功
              if(res.token) {
                // 储存 token
                localStorage.token = res.token
              }
            })
            .catch(error => {
              // 登录失败
              // 验证后端返回的错误字段,如果匹配,提示用户
              // axios 配置里必须要 return Promise.reject(error.response.data) 才能拿到错误字段
              if(error.xxx == 'xxx') {
                alert('用户名或密码错误!')
              }
            })
        }
      }
    }
    

    以上代码在好几个项目里都正常使用,没有问题
    具体还可以参照我写的一个开源项目
    vue-shop

    码字不易,如果对你有用,请支持点赞~谢谢 :)

    相关文章

      网友评论

      • f1a94e9a1ea7:请问AxiosPlugin.js文件里对响应数据做点事具体是做了什么
        if(!res.data.success){
        alert(res.error_msg)
        return Promise.reject(res)
        }
        有些返回的数据里没有success
        Yi罐可乐:@不是肉馅的包子 具体怎么约定一次请求是否成功,可以自己定制,我这个只供参考哈
      • f1a94e9a1ea7:请问那个组件外部为什么还要Axios.post(),意思是Login.vue组件 export 上面还要加上:import { Axios } from 'xxx/xxx/AxiosPlugin'
        Axios.post(url, data) 吗
        Yi罐可乐:@不是肉馅的包子 不需要,你可以看一下 main.js 里的逻辑
      • 性格但丁:你好,请教一下,我想再 axios 的拦截器中获取 vue 实例,目的是想获取 router,这个要如何解决?
        Yi罐可乐:@性格但丁 不用通过 vue 示例来获取 router,直接 import 'router' from 'xxx/router' 就行
      • Mr_houzi:不理解是怎么加密token的,保证接口不被伪装请求?
      • f3e51b85aba2:vue-order-admin 中 http://rzk-in.wo946.com/api/api/ 是python写的吗?
        Mr_houzi:不理解是怎么加密token的,保证接口不被伪装请求?
        f3e51b85aba2:@Yi罐可乐 希望可以写一篇Axios配置JWT For iview-admin简化版的,哈哈
        https://github.com/iview/iview-admin/tree/template
        Yi罐可乐:@文韬_acd8 哈哈,不是。
      • rancho_web:楼主能贴下完整代码吗 下面的 AxiosPlugin 怎么直接没有install(Vue)
        rancho_web:@Yi罐可乐 谢谢
      • 1cd3909eb544:你好,请教个问题:token过期时间设置多久合适?如果没有手动点退出,那直接关闭浏览器再登录还是有的吧?如果我设置过期2小时,那我在登录到2小时的时候不是无法正常访问需要重新登录了吗?如何自动刷新token呢?谢谢
        Yi罐可乐:@专治闹20年 网站的话 2 0~ 30分钟,APP 的话可以久一点。token 存在 localStorage 里关闭浏览器不会消失。可以做一个更新 token 的接口。
      • 兔头咖啡:大可乐,太牛XXXXXXXXXXXX
      • 梦想成为超人:膜拜 Django 大佬 :yum:

      本文标题:Vue 进阶教程之:Axios配置JWT/封装插件/发送表单数据

      本文链接:https://www.haomeiwen.com/subject/icuocxtx.html