zoukankan      html  css  js  c++  java
  • axios和fetch

    前面的vuex提到了异步请求,在vue里异步请求怎么请求呢,很显然jq.ajax是不用了,不是不能用,而是没必要,jq是操作dom的工具,强行用浪费功能,还会加大打包后的体积,而且是没有promise的,所以有大佬封装了新的ajax,名字叫axios,也是vue的作者尤雨溪推荐使用的,这个axios是可以直接在nodejs端使用的

    自行百度安装,axios是没有封装成可以让vue.use()的这种使用模式的,也没必要,但最好二次封装下

    二次封装
    先去创建一个util的工具文件夹,在里面再新建一个叫request.js文件,直接上代码

    // 引入axios
    import axios from 'axios'
    import store from 'store'
    
    const service = axios.create({
      // url = base url + request url
      // 这是请求的前缀的三元运算符,是需要配合proxy使用的
      // process.env.NODE_ENV 是nodejs的全局变量,需要懂点nodejs才知道
      // 意思是如果是开发【development】环境
      // 前缀就是当前本地地址 "localhost:端口" + "/proxy" + "url值"
      // 如果不是开发环境,意思就是线上环境,即打包后上线的环境,你让用户请求 "localhost:3000" 肯定是请求不到的
      // 所以打包出来的就是 "http://xxx.com" + "url值"
      baseURL: process.env.NODE_ENV === 'development' ? '/proxy' : 'http://xxx.com', //process.env.VUE_APP_BASE_API
      // 最长等待时间
      timeout: 5000 // request timeout
    })
    
    // 请求前的操作,config参数是请求前的一切数据,可以打印查看
    service.interceptors.request.use(
      config => {
        // 在这里可以做权限的判断
        if(0){
            // 不同意请求 return 一个Promise.reject
            return Promise.reject("当前账号无该请求权限")
        }
        // 从vuex里取token值,如果这么写上面需要去引入vuex
        if (store.getters.token) {
          // 可以自动添加请求头token,就不需要自己手动一次次去写了
          // 什么是token,面试题篇里有
          config.headers['X-Token'] = getToken()
        }
        // 如果同意请求,需要return config
        return config
      },
      error => {
        // 错误处理
        console.log(error) // for debug
        return Promise.reject(error)
      }
    )
    
    // 请求后的操作,response是axios二次封装的返回值
    service.interceptors.response.use(
      response => {
        // 在返回值可以看到请求的地址
        const url = response.config.url;
        // 这是真正的返回数据
        const res = response.data;
        // 可以做一些统一的返回值处理
        if (res.code === 2000) {
          // 成功就返回res
          return res
        } else {
          return Promise.reject(new Error(res.msg || 'Error'))
        }
      },
      error => {
        // 无返回的错误处理
        return Promise.reject(error)
      }
    )
    // 这就是整个插件了
    export default service
    

    如何使用

    写好接口
    建议是统一一个文件夹叫req或者叫api,然后根据模块放置请求

    image.png

    // 引入封装好的插件
    import request from '@/utils/request'
    
    export function getInfo(opt) {
      return request({
        // 这个在开发环境会变成 "http:localhost:端口" + "/proxy" + "/user/info"
        // 正式环境就是 "http:baidu.com" + "/user/info"
        url: '/user/info',  
        method: 'get',
        // get用params
        params: opt
      })
    }
    
    export function post(opt) {
      return request({
        url: '/post',  
        method: 'post',
        // post用data
        data: opt
      })
    }
    

    在vue文件里调用
    在vuex使用查看上一篇,跟在vue文件里写法一样的

    // 引入
    import { getInfo,post} from 'api/user';
    
    export default {
        data(){
            return { ... }
        },
        mounted(){
           getInfo({id:123123}).then(res=>{
              console.log(res)
           })
        },
    }
    
    // 因为是promise请求还可以用
    Promise.all([getInfo(),post()])
    // 或者async
    async mounted(){
         var res = await getInfo({id:123123})
    },
    

    上传文件

    export function upload(formdata) {
      return request({
        url: '/uploadFile',
        method: 'post',
        data: formdata,
        headers: { 'Content-Type': 'multipart/form-data' },
      })
    }
    

    注意,axios的post请求是会自动转成了json字符串【跟文件上传无关】,如果后端说他不要json格式,一定要key-value的form表单格式,就不能用上面的封装了,得安装qs插件,还要修改headers

    qs插件

    import qs from 'qs';
    
    export function upload(formdata) {
      return request({
        url: '/form',
        method: 'post',
        data: qs.stringify(data),
        headers: {'content-type': 'application/x-www-form-urlencoded'},
      })
    }
    

    就上面这么写,是发不出去请求的

    我们上面出现过的这两句话

    1. 这个在开发环境会变成 "http:localhost:端口" + "/proxy" + "/user/info"
    2. 正式环境就是 "http:baidu.com" + "/user/info"
    

    在jq-ajax请求的那一篇的最后面就写过,请求需要满足的条件

    1. 需要存在这个请求地址,第一个请求地址一看就没有,脚手架里怎么会有这个接口呢
    2. 需要浏览器不跨域

    如何满足上面的两个条件,查看下一篇

    补充fetch
    fetch并不是一个插件,是跟xhr一样的,原生的,请求方式,目前兼容不好,普及不多,这里做个记录

    fetch('https://www.baidu.com/search/error.html', {
        method: 'POST',
        credentials: 'xxx' // 强制加入凭据头
        headers: new Headers({
          'Content-Type': 'application/x-www-form-urlencoded' // 指定提交方式为表单提交
          'Accept': 'application/json' // 通过头指定,获取的数据类型是JSON
        }),
        body: new URLSearchParams([["foo", 1],["bar", 2]]).toString()
    })
    .then((res)=>{
        return res.text()
    })
    .then((res)=>{
        console.log(res)
    })
    
  • 相关阅读:
    CentOS查看和修改MySQL字符集
    centos修改mysql密码或者进入mysql后解决Access denied for user ''@'localhost' to database 'mysql错误
    Centos设置开机启动Apache和Mysql
    centos搭建ftp服务器
    1QT在线帮助文档
    storm学习
    java提高篇之理解java的三大特性——多态
    基于AQS的锁
    反转单链表的几种方法
    Java:基于LinkedList实现栈和队列
  • 原文地址:https://www.cnblogs.com/pengdt/p/12046411.html
Copyright © 2011-2022 走看看