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)
}