vue使用axios拦截配置(涵盖fecth及多样拦截配置)

10 篇文章 0 订阅
2 篇文章 0 订阅
import axios from 'axios'
import {Message} from 'iview'

let util = {};
axios.defaults.withCredentials = true;


util.ajax = axios.create({
  // baseURL: ajaxUrl,
  timeout: 120000,
  withCredentials: true
});

axios.interceptors.request.use(
  config => {
    config.headers = {
      'Content-Type':'application/json'
    };
    return config;
  },
  error => {
    return Promise.reject(error)
  }
);

util.request = function (options) {
  axios.request({
    // baseURL: ajaxUrl,
    withCredentials: true,
    method: options.method || 'post',
    url: `${options.url}`,
    headers: {'X-Requested-With': 'XMLHttpRequest'},
    params: options.params,
    data: options.data,
    transformRequest: [function (data) {
      // 这里可以在发送请求之前对请求数据做处理,比如form-data格式化等,这里可以使用开头引入的Qs(这个模块在安装axios的时候就已经安装了,不需要另外安装)
      if (null !== data && '' !== data && typeof(data) !== 'undefined') {
        data = JSON.stringify(data)
      }
      return data
    }],
    timeout: options.timeout || 120 * 1000
  }).then(function (response) {
    // 登陆成功
    let responseData = response.data;
    options.success && options.success(responseData)
  }).catch(function (error) {
    let response = error.response;
    let errorData = '';
    if (null !== response && '' !== response && typeof(response) !== 'undefined') {
      errorData = error.response.data;
      let code = response.status;
      if (code === 401) {
        Message.error('登陆会话超时,请重新登录!');
        options.error && options.error(error);
        setTimeout(jumpLogin, 2000);
      } else if (code === 504) {
        Message.error('服务器未连接,请重新登录!');
        options.error && options.error(error);
        setTimeout(jumpLogin, 2000);
      } else {
        if (null !== errorData && '' !== errorData && typeof(errorData) !== 'undefined') {
          let msg = errorData.list;
          if (null !== msg && '' !== msg && typeof(msg) !== 'undefined') {
            Message.error(msg);
          } else {
            Message.error('请求异常');
          }
        } else {
          Message.error('请求异常');
        }
        options.error && options.error(error)
      }
    }
  })

};


export default util

特别针对基础拦截配置interceptors做简单说明

axios.interceptors.request.use(
  config => {
    config.headers = {
      'Content-Type':'application/json'
    };
    return config;
  },
  error => {
    return Promise.reject(error)
  }
);
 config.headers = {
      'Content-Type':'application/json'
    };
config.headers   作为配置拦截的请求头常常作为识别标志

另外一种配置axios配置

// 引入axios
import axios from 'axios'
import qs from 'qs'
import { Message } from 'iview'

let cancel; let promiseArr = {}
const CancelToken = axios.CancelToken
// 请求拦截器
axios.interceptors.request.use(config => {
    // 发起请求时,取消掉当前正在进行的相同请求
    if (promiseArr[config.url]) {
        promiseArr[config.url]('操作取消')
        promiseArr[config.url] = cancel
    } else {
        promiseArr[config.url] = cancel
    }
    return config
}, error => {
    return Promise.reject(error)
})

// 响应拦截器即异常处理
axios.interceptors.response.use(response => {
    return response
}, err => {
    if (err && err.response) {
        switch (err.response.status) {
        case 400:
            err.message = '错误请求'
            break
        case 401:
            err.message = '未授权,请重新登录'
            break
        case 403:
            err.message = '拒绝访问'
            break
        case 404:
            err.message = '请求错误,未找到该资源'
            break
        case 405:
            err.message = '请求方法未允许'
            break
        case 408:
            err.message = '请求超时'
            break
        case 500:
            err.message = '服务器端出错'
            break
        case 501:
            err.message = '网络未实现'
            break
        case 502:
            err.message = '网络错误'
            break
        case 503:
            err.message = '服务不可用'
            break
        case 504:
            err.message = '网络超时'
            break
        case 505:
            err.message = 'http版本不支持该请求'
            break
        default:
            err.message = `连接错误${err.response.status}`
        }
    } else {
        err.message = '连接到服务器失败'
    }
    Message.error(err.message)
    return Promise.resolve(err.response)
})

// axios.defaults.baseURL = '/api'
axios.defaults.withCredentials = true
// 设置默认请求头
axios.defaults.headers = {
    'X-Requested-With': 'XMLHttpRequest',
    'Accept': 'application/json',
    'Content-Type': 'application/json;charset=utf-8'
}
axios.defaults.timeout = 10000

/**
 * 请求
 * @param url       接口地址
 * @param data      传递数据格式
 * @param type      请求方式
 */
export const fetch = (url = '', data = {}, type = 'GET') => {
    return new Promise((resolve, reject) => {
        type = type.toUpperCase()
        url = `/api/${url}`

        if (type === 'GET' || type === 'DELETE') {
            axios({
                method: type,
                url,
                params: data,
                cancelToken: new CancelToken(c => { cancel = c })
            }).then(res => {
                resolve(res.data)
            })
        }

        if (type === 'POST' || type === 'PUT' || type === 'PATCH') {
            axios({
                method: type,
                url,
                data: qs.stringify(data),
                cancelToken: new CancelToken(c => { cancel = c })
            }).then(res => {
                resolve(res.data)
            })
        }
    })
}```
特别注意错误异常捕获码如“401”!!!!等等应和当前服务端的配置吗一致!!通俗点讲就是你们的后端的错误码应该和你的错误码保持一致!401代表的含义是一样的才可以;

## fecth配置如下
新建异常捕获文件`process_request_conf.js`

```kotlin
import { Message } from 'iview'
export const process_error = (error) => {
    let message = error.message
    if (message) {
        let code = error.statusCode
        console.log(code)
        switch (code) {
        case 300:
            Message.error('登陆会话超时,请重新登录!')
            window.location.href = '/'
            return
        case 302:
            Message.error('CAS服务未登录,请重新登录!')
            redirectUrl()
            return
        case 504:
            Message.error('服务器未连接,请重新登录!')
            window.location.href = '/'
            return
        case 401:
            Message.error('服务器未连接,请重新登录!')
            window.location.href = '#/login'
            return
        default:
            let msg = message || '请求异常'
            Message.error(msg)
        }
    }
}
export const redirectUrl = () => {
    let redirectUrl = `http://${window.location.hostname}/login?service=${window.location.href}`
    window.location.href = redirectUrl
}

这里是我个人的项目使用配置同志们在使用的时候请干掉不用的配置及修改不要的错误捕获减少代码冗余!!

*fecth配置如下

`import { redirectUrl } from './process_request_conf'
export default async(url = '', data = {}, type = 'GET', headerConfig = {}, method = 'fetch') => {
    type = type.toUpperCase()
    url = `/api/${url}`

    if (type === 'GET') {
        let dataStr = '' // 数据拼接字符串
        Object.keys(data).forEach(key => {
            dataStr += key + '=' + data[key] + '&'
        })

        if (dataStr !== '') {
            dataStr = dataStr.substr(0, dataStr.lastIndexOf('&'))
            url = url + '?' + dataStr
        }
    }

    if (window.fetch && method === 'fetch') {
        let requestConfig = {
            credentials: 'include',
            method: type,
            headers: {
                'Accept': 'application/json',
                'Content-Type': headerConfig['contentType'] ? headerConfig['contentType'] : 'application/json'
            },
            mode: 'no-cors',
            cache: 'no-cache'
        }

        if (type === 'POST' || type === 'DELETE') {
            requestConfig.mode = 'cors'
            Object.defineProperty(requestConfig, 'body', { value: JSON.stringify(data) })
        }

        try {
            let response = null
            response = await fetch(url, requestConfig)
            if (response.type == 'opaque' || response.redirected) return redirectUrl()
            const responseJson = await response.json()
            return responseJson
        } catch (error) {
            throw new Error(error)
        }
    } else {
        return new Promise((resolve, reject) => {
            let requestObj
            if (window.XMLHttpRequest) {
                requestObj = new XMLHttpRequest()
            } else if (window.ActiveXObject) {
                requestObj = new ActiveXObject()
            }

            let sendData = ''
            if (type === 'POST') { sendData = JSON.stringify(data) }

            let auth = sessionStorage.getItem('token') || ''
            requestObj.open(type, url, true)
            requestObj.setRequestHeader('Content-type', 'application/x-www-form-urlencoded')
            requestObj.setRequestHeader('Authorization', auth)
            requestObj.send(sendData)

            requestObj.onreadystatechange = () => {
                if (requestObj.readyState === 4) {
                    if (requestObj.status === 200) {
                        let obj = requestObj.response
                        if (typeof obj !== 'object') {
                            obj = JSON.parse(obj)
                        }
                        resolve(obj) // 更改status pending -> fulflled(resolved)
                    } else {
                        reject(requestObj) // 更改status pending -> rejected
                    }
                }
            }
        })
    }
}`*

这里放一个我们实际的使用接口案例注意我们的后台有点奇葩 所以不要大惊小怪 我接受这个项目组做法也做了很大的心里斗争!!!

post单参数方式(拼接)

export const getSofDownload = (filename) => {
    return fetch(`jzweb/softDownload/downloadList?filename=${filename}`, {}, 'POST')
}

post多参数对象方式含对象嵌套{xx:{}}

export const softDownload = (sendData) => {
    return fetch('/jzweb/softDownload/save', {
        fileName: sendData.fileName,
        filePath: sendData.filePath,
        fileSize: sendData.fileSize,
        name: sendData.name,
        type: sendData.type
    }, 'POST')
}

普通get方式

export const appPageData = (sendData) => {
    return fetch('jzweb/platform/pagePlatform', {
        sort: sendData.sort,
        page: sendData.current,
        size: sendData.size
    })
}

拼接式get

export const getDeptChildren = (departId) => {
    return fetch('jzweb/depart/departByPid/' + departId)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值