一般我们会在src目录下新建http.js和api.js
http.js网络请求的封装
api.js接口的封装
http.js
import axios from 'axios'
import {
Loading, Message} from 'element-ui' // 这里我是使用elementUI的组件来给提示
// import router from '@/router'
let loadingInstance = null // 加载全局的loading
const instance = axios.create({
//创建axios实例,在这里可以设置请求的默认配置
timeout: 1000 * 30, // 设置超时时间10s
baseURL: '/', //根据自己配置的反向代理去设置不同环境的baeUrl
})
// 文档中的统一设置post请求头。下面会说到post请求的几种'Content-Type'
instance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'
// instance.defaults.proxy
let httpCode = {
//这里我简单列出一些常见的http状态码信息,可以自己去调整配置
400: '请求参数错误',
401: '权限不足, 请重新登录',
403: '服务器拒绝本次访问',
404: '请求资源未找到',
500: '内部服务器错误',
501: '服务器不支持该请求中使用的方法',
502: '网关错误',
504: '网关超时'
}
/**
* 根据cookie名,获取cookie
* @param name
* @returns {null}
*/
function getCookie(name) {
var cookieValue = null;
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i].trim()
// Does this cookie string begin with the name we want?
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
function csrfSafeMethod(method) {
// 这些HTTP方法不要求CSRF包含
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
/** 添加请求拦截器 **/
instance.interceptors.request.use(config => {
config.headers['X-CSRFToken'] = getCookie('csrftoken') || ''
loadingInstance = Loading.service({
// 发起请求时加载全局loading,请求失败或有响应时会关闭
spinner: 'fa fa-spinner fa-spin fa-3x fa-fw',
text: '拼命加载中...'
})
// 在这里:可以根据业务需求可以在发送请求之前做些什么:例如我这个是导出文件的接口,因为返回的是二进制流,所以需要设置请求响应类型为blob,就可以在此处设置。
if (config.url.includes('pur/contract/export')) {
config.headers['responseType'] = 'blob'
}
// 我这里是文件上传,发送的是二进制流,所以需要设置请求头的'Content-Type'
if (config.url.includes('pur/contract/upload')) {
config.headers['Content-Type'] = 'multipart/form-data'
}
return config
}, error => {
// 对请求错误做些什么
return Promise.reject(error)
})
/** 添加响应拦截器 **/
instance.interceptors.response.use(response => {
loadingInstance.close()
return Promise.resolve(response.data)
// if (response.data.status === 'ok') { // 响应结果里的status: ok是我与后台的约定,大家可以根据实际情况去做对应的判断
// return Promise.resolve(response.data)
// } else {
// Message({
// message: response.data.message,
// type: 'error'
// })
// return Promise.reject(response.data.message)
// }
}, error => {
loadingInstance.close()
if (error.response) {
// 根据请求失败的http状态码去给用户相应的提示
let tips = error.response.status in httpCode ? httpCode[error.response.status] : error.response.data.message
Message({
message: tips,
type: 'error'
})
if (error.response.status === 401) {
// token或者登陆失效情况下跳转到登录页面,根据实际情况,在这里可以根据不同的响应错误结果,做对应的事。这里我以401判断为例
// router.push({
// path: `/login`
// })
}
return Promise.reject(error)
} else {
Message({
message: '请求超时, 请刷新重试',
type: 'error'
})
return Promise.reject(new Error('请求超时, 请刷新重试'))
}
})
/* 统一封装get请求 */
export const get = (url, params, config = {
}) => {
return new Promise((resolve, reject) => {
instance({
method: 'get',
url,
params,
...config
}).then(response => {
resolve(response)
}).catch(error => {
reject(error)
})
})
}
/* 统一封装post请求 */
export const post = (url, data, config = {
}) => {
return new Promise((resolve, reject) => {
instance({
method: 'post',
url,
data,
...config
}).then(response => {
resolve(response)
}).catch(error => {
reject(error)
})
})
}
export const axiosInstance = instance;
/* 或者写成下面这样: Promise.resolve() 和 Promise.reject()返回的是promise对象,二者都是语法糖 */
// export const post = (url, data, config = {}) => {
// return instance({
// method: 'post',
// url,
// data,
// ...config
// }).then(response => {
// return Promise.resolve(response)
// }).catch(error => {
// return Promise.reject(error)
// })
// }
api.js
import {
get} from "@/request/http";
/**
*
* @param p
* @returns {Promise}
*/
export const test = p => get('/test', p);
vue.config.js
module.exports = {
lintOnSave: 'warning'
}
// const path = require('path')
const Terser = require('terser-webpack-plugin')
// const resolve = dir => path.join(__dirname, dir)
/**
* 环境根目录
*/
// let BaseURL = {
// prod: 'http://localhost:8000',
// dev: 'http://localhost:8000',
// }
const URL = "http://xxx:xx";
module.exports = {
lintOnSave: false,//取消Eslint检测
productionSourceMap: false,
publicPath: process.env.NODE_ENV === 'production'
? '/'
: '/',
configureWebpack: config => {
const plugins = [
new Terser({
terserOptions: {
output: {
// 删除注释
comments: false
},
compress: {
warnings: false,
// 删除 console
// drop_console: true
pure_funcs: ['console.log', 'console.warn', 'console.info']
}
}
})
]
// 只有打包生产环境才需要将console删除
if (process.env.NODE_ENV === 'production') {
config.plugins = [...config.plugins, ...plugins]
}
},
devServer: {
open: false,
disableHostCheck: true,
proxy: {
'/': {
target: URL,
}
}
}
}
调用的地方:
import {
test} from "@/request/api";
let params =
{
xx: ''
}
test(params).then(r => {
console.log(r)
})