axios封装

axios封装

request.js

import Vue from "vue"
import axios from "axios"
import { Message } from "element-ui"
import * as streamSaver from "streamsaver"
import vm from "@/main.js"

let loading
axios.defaults.withCredentials = true
// 创建axios实例
const service = axios.create({
  baseURL: "/",
  timeout: 30000,
  headers: {
    "Content-Type": "application/json",
  },
})

// request拦截器
service.interceptors.request.use(
  (config) => {
    loading = Vue.prototype.$loading({
      lock: true,
      text: "Loading",
      spinner: "el-icon-loading",
      background: "rgba(0, 0, 0, 0.7)",
    })
    if (localStorage.token && localStorage.userId) {
      config.headers["token"] = `${localStorage.token}`
      config.headers["userId"] = `${localStorage.userId}`
    }
    if (config.method === "post") {
      config.data = JSON.stringify({
        ...config.data,
      })
    }

    return config
  },
  (error) => {
    Promise.reject(error)
  }
)

// response拦截器
service.interceptors.response.use(
  (response) => {
    loading.close()
    const res = response.data

    // 文档 content-type 类型
    let docs = ['application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'application/msword', 'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'text/plain']
    // 图片 content-type 类型
    let img = ['application/octet-stream', 'image/jpeg', 'image/png', 'image/gif', 'image/bmp', 'image/svg+xml', 'image/webp']
    // 未知 content-type 类型
    let file = ['application/octet-stream']

    const header = response.headers['content-type'] || ''
    if ([...docs, ...img, ...file].includes(header.replace(';charset=utf-8', ''))) {
      return res
    }

    handleResponseData(res)
  },
  (error) => {
    loading.close()
    Message({
      message: "服务器异常",
      type: "error",
      duration: 3 * 1000,
    })
    return Promise.reject(error)
  }
)
// 用于文件上传(不需要Qs.stringify,直接添加form-data就行)
const fileService = axios.create({
  baseURL: "/",
  timeout: 30000,
  headers: {
    "Content-Type": "multipart/form-data",
  },
})

// request拦截器
fileService.interceptors.request.use(
  (config) => {
    loading = Vue.prototype.$loading({
      lock: true,
      text: "Loading",
      spinner: "el-icon-loading",
      background: "rgba(0, 0, 0, 0.7)",
    })
   
    return config
  },
  (error) => {
    loading.close()
    Promise.reject(error)
  }
)

// response拦截器
fileService.interceptors.response.use(
  (response) => {
    const res = response.data
    loading.close()

    handleResponseData(res)
  },
  (error) => {
    loading.close()
    Message({
      message: error.message,
      type: "error",
      duration: 3 * 1000,
    })
    return Promise.reject(error)
  }
)


/**
 * 处理响应数据
 * @param res 响应数据
 * @returns 
 */
function handleResponseData(res) {
    if (res.code === 0 || res.code === 200 ) {
      return res
    } else if (res.code === 500) {
      Message({
        message: res.msg || res.message || '系统异常',
        type: "error",
        duration: 10 * 1000,
      })
      return res
    } else if (res.code === 401) {
      Message({
        message: "请登录",
        type: "warning",
        duration: 3 * 1000,
      })
      localStorage.clear()
      vm.$router.push("/")
      return res
    } else {
      Message({
        message: "连接超时",
        type: "error",
        duration: 3 * 1000,
      })
      return Promise.reject(res)
    }
}






/**
 * get方法,对应get请求
 * @param {String} url [请求的url地址]
 * @param {Object} params [请求时携带的参数]
 */
export function get(url, params){
	return new Promise((resolve, reject) =>{
		service.get(url, {
			params: params
		}).then(res => {
			resolve(res);
		}).catch(err =>{
			reject(err)
	})
  });
}

/**
 * post方法,对应post请求
 * @param {String} url [请求的url地址]
 * @param {Object} params [请求时携带的参数]
 */
export function post(url, params, config = {}) {
	return new Promise((resolve, reject) => {
    service.post(url, params, {
      ...config
    })
		.then(res => {
			resolve(res);
		})
		.catch(err =>{
			reject(err)
		})
	});
}




/**
 * @description 一般导出(小文件下载) post请求
 * @param  { String } url 下载路径
 * @param  { Object } data 下载参数
 */
export const download = function(url, data = {}) {
  service({ url, method: 'POST', data, responseType: 'blob' }).then(blob => {
      const fileNameMatch = blob['content-disposition'].match(/filename\*?=['"]?(?:UTF-\d['"]*)?([^;\r\n"']*)['"]?;?/i)
      const encodedFileName = fileNameMatch ? fileNameMatch[1] : null
      const decodedFileName = encodedFileName ? decodeURIComponent(encodedFileName) : null
      const downloadLink = document.createElement('a')
      downloadLink.href = URL.createObjectURL(blob)
      downloadLink.download = decodedFileName
      downloadLink.click()
      URL.revokeObjectURL(downloadLink.href)
  })
}


/**
 * @description 导出大文件
 * @param  { String } url 下载路径
 * @param  { String } fileName 文件名字
 */
export const downloadResource = async function (url, fileName) {
  let filename = fileName
  if (!fileName) {
      filename = url.substring(url.lastIndexOf('/') + 1);
  }
  return fetch(url, {
      method: 'GET',
      cache: 'no-cache',
  }).then(res => {
      const fileStream = streamSaver.createWriteStream(filename,{
          //增加小视图,体现下载进度条与总大小
          size : res.headers.get("content-length")
      })
      const readableStream = res.body
      if (window.WritableStream && readableStream.pipeTo) {
          return readableStream.pipeTo(fileStream)
      }
      window.writer = fileStream.getWriter()
      const reader = res.body.getReader()
      const pump = () => reader.read()
          .then(res => res.done
              ? window.writer.close()
              : window.writer.write(res.value).then(pump))
      pump()
  })
}


/**
 * 上传文件
 * @param url 请求路径
 * @param formData 上传参数
 * @returns
 */
export const upload = function(url, formData = {}) {
    return new Promise((resolve, reject) => {
      fileService.post(url, formData).then(res => {
        resolve(res);
      }) .catch(err =>{
        reject(err)
      })
    });

}



export { service, fileService }



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zsd_666

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值