接口封装需要考虑的问题。

import axios from 'axios'
// import qs from 'qs'
import store from '@/store'
import router from '@/router'
import { Message } from 'element-ui'
import config from '@/static/config.json'
// isSTip:操作成功的提示
// isFTip:操作失败的提示
// isDownload:是否下载文件
  // 1.疑问:为什么请求一次接口,拦截器会拦截3次,甚至6次
  // 回答拦截器只能创建一次,不然多次执行,就会创建多个拦截器。
  // 导致上面问题。解决办法,拦截器不能写在多次执行的函数里面
axios.interceptors.request.use(
  config => {
  //请求头增加token
    if (store.state.token) {
      config.headers.Authorization = `${store.state.token}`
    }
    //如果后台要求的数据格式是form表单提交数据,需要用qs转数据。
    //axios默认使用json格式传给后台。
    if(config.headers.contentType=="application/x-www-form-urlencoded"){
    	config.data = qs(config.data)
    }
    return config
  },
  error => {
    Promise.reject(error)
  }
)
// 2.疑问:公共处理写在响应拦截器中和axios.then().catch()中写有什么区别?
// 请求失败的拦截,一般是不会触发,也不会在这里面写公共处理。只会把错误信息Promise.reject(err)出去
// 响应失败的拦截,一般服务异常情况:1.404,500会在这里拦截到,2.请求ip服务连接失败,也会在这拦截到。
// 请求失败的拦截,响应失败的拦截,最终都会在axios.catch()能捕获到。
// 3.疑问:请求成功的处理,在axios.then()中处理和在响应拦截器成功的回调中处理,有啥区别?
// 答:3.1.如果页面中需要做一些公共处理,比如下载文件操作,是否提示操作成功的提示,或者操作失败的提示。最好在axios.then中来添加执行操作。

axios.interceptors.response.use(
  response => {
    // 1.处理返回的数据格式。(暂不处理)//有可能后台返回的数据格式不是前端能用的,比如有些后台会返回json字符串,那么就需要在这处理数据。
    return response
  },
  error => {
    return Promise.reject(error)
  }
)
function downloadFile(res){
  var blob = res.data;
  // FileReader主要用于将文件内容读入内存
  var reader = new FileReader();
  reader.readAsDataURL(blob);
  // onload当读取操作成功完成时调用
  reader.onload = function(e) {
    var a = document.createElement('a');
    // 获取文件名fileName
    var fileName = res.headers["content-disposition"].split("=");
    fileName = fileName[fileName.length - 1];
    fileName = fileName.replace(/"/g, "");
    a.download = fileName;
    a.href = e.target.result;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
  }
}
const service = function(configData){
  return new Promise((reslove, reject)=>{
    axios({
      baseURL: process.env.BASE_API ? process.env.BASE_API : config.appBaseUrl, // api的base_url
      timeout: 1000 * 60 * 2, // request timeout
      withCredentials: false,
      data: configData.data,
      method: configData.method,
      url: configData.url,
      headers: configData.headers,//configData.headers传进来是{}对象。
      responseType: configData.responseType?configData.responseType:'json'
    }).then((res)=>{
      // 1.code==100001,与403001,鉴权失效,跳转到登录页。
      const code = response.data.code
      if(code==100001){
        router.push('/sign')
      }else if(code==403001){
        router.push('/sign')
      }
      // 2.是否操作成功或者失败的提示信息。
      if(configData.isFTip){
        Message({
          message: res.message,
          type: 'error',
          duration: 1 * 1000
        })
      }
      if(configData.isSTip){
        Message({
          message: res.message,
          type: 'success',
          duration: 1 * 1000
        })
      }
      // 1.文件下载
      if(configData.isDownload){
        downloadFile(res)
      }
      reslove(res)
    }).catch((err)=>{
      Message({
        message: '服务异常!',
        type: 'error',
        duration: 3 * 1000
      })
      reject(err)
    })
  })
}
export default service
//1.这个文件返回一个函数给页面使用,调用这个函数,会直接调axios,他返回的是一个promise对象。这样写,相比较直接返回出去是个axios对象的好处是,可扩展性强。能在axios中再加入公共处理。
//2.如果像恒生本部的封装写法,返回出去的是个axios对象,页面中调用接口,传的参数会直接合并到axios的config中。
//  3.后台返给前端的数据是否需要处理:是html,或者文档流,或者是json字符串格式,或者是普通的js对象。
// 4.(在路由拦截器里面也要做拦截,如果缓存中没有用户信息,或者token,也要跳转到登录页)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值