配置小贴士
封装请求头时注意一下Content-Type
属性,看后台使用什么方式接收,如是表单形式接收需要设置为application/x-www-form-urlencoded;charset=utf-8
或者multipart/form-data
,此时要使用qs
插件处理数据将json
数据转化为from
数据,方法如下:
import qs from 'qs'; // json --> form
export function post(url, data){
return new Promise((resolve,reject) => {
request({
method: 'post',
url: url,
data: qs.stringify(data)
}).then(res => {
if (res.flag) {
resolve(res)
} else {
Message({
message: res.message,
type: 'error',
duration: 2 * 1000
})
}
}).catch(err => {
Message({
message: '网络异常',
type: 'error',
duration: 2 * 1000
})
reject(err)
})
})
}
axios
的配置中withCredentials: true
配置表示允许携带cookie
axios.create({
withCredentials: true,
baseURL: baseUrl, // 基础路径
timeout: 5000, // 请求超时, 5000毫秒
headers: { // 添加 header 头信息
// json形式传输
'Content-Type': 'application/json;charset=utf-8'
}
});
如需了解更多axios配置,点我
上代码
封装的request.js
公共请求文件
import axios from "axios"; import { baseUrl } from "./env.js" import router from '@/router' import { Loading, Message } from 'element-ui' // import qs from 'qs'; // json --> form const request = axios.create({ // withCredentials: true, baseURL: baseUrl, // 基础路径 timeout: 5000, // 请求超时, 5000毫秒 headers: { // 添加 header 头信息 // 使用时结合qs使用,将json转化为form形式传输,需要解开上面的qs的注释 // 'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8' // json形式传输 'Content-Type': 'application/json;charset=utf-8' } }); // 加载数据时,打开和关闭动画特效 const loading = { loadingInstance: null, // Loading 实例 open: function() { // console.log('加载中', this.loadingInstance) if(this.loadingInstance === null) { // 创建单例,防止切换路由重复加载 // console.log('创建实例加载') this.loadingInstance = Loading.service({ text: '拼命加载中...', // customClass: 'loadingClass', // target: '.main', // 效果显示区域 background: '#fff' }) } }, close: function() { // 关闭加载 if(this.loadingInstance !== null) { this.loadingInstance.close() // console.log('结束加载') } this.loadingInstance = null } } // 请求拦截器 request.interceptors.request.use( config => { let _token = localStorage.getItem('token') if (_token) { config.headers['Authorization'] = _token } // 这里关闭所有的消息提示,避免重复报错 Message.closeAll() // 打开加载效果 loading.open() return config; }, err => { // 出现异常 loading.close() return Promise.reject(err) } ); // 响应拦截器 request.interceptors.response.use( res => { loading.close() const response = res.data if (response.code !== 200 && response.status !== 200) { if (response.code === 20000 || response.code === 20001) { Message({ message: response.message, type: 'error', duration: 5 * 1000 }) // 处理异常状态清除token跳转回登录页 localStorage.removeItem('token') router.replace('login') // return Promise.reject('error') } else if (response.code === 90001) { Message({ message: '网络异常', type: 'error', duration: 5 * 1000 }) } else { Message({ message: response.message, type: 'error', duration: 5 * 1000 }) } } return response }, err => { // 出现异常 loading.close() return Promise.reject(err); } ); export function post(url, data){ return new Promise((resolve,reject) => { request({ method: 'post', url: url, data: data }).then(res => { // 这里看项目情况,我这边是用flag来判断请求成功与否,虽然有code===200可以判断,但后台小哥哥给了这个字段,不忍心不用 if (res.flag) { // 请求成功处理,不成功则消息提示 resolve(res) } else { Message({ message: res.message, type: 'error', duration: 2 * 1000 }) } }).catch(err => { reject(err) }) }) } export function get(url){ return new Promise((resolve,reject) => { request.get(url).then(res => { if (res.flag) { resolve(res) } else { Message({ message: res.message, type: 'error', duration: 2 * 1000 }) } }).catch(err => { reject(err) }) }) }
封装请求到这里就结束了,如果不会使用,请看下一篇 手摸手封装vue中api文件,让项目更容易维护