axios的get、post、文件上传、下载封装

您所在的位置:网站首页 get可以上传文件吗 axios的get、post、文件上传、下载封装

axios的get、post、文件上传、下载封装

2023-11-17 13:32| 来源: 网络整理| 查看: 265

该文只讲封装,不涉及下载安装原理讲解。以下所有的封装代码需要写在一个文件内并将其暴露,并在写入 API 的文件内引入。

创建http请求

利用axios创建一个实例:

const baseURL = `/${process.env.VUE_APP_API_PREFIX}`; // 接口基本路径 const http = axios.create({ timeout: timeOut, withCredentials: true, headers: { 'X-Requested-With': 'XMLHttpRequest', 'X-CSRF-TOKEN': getToken() }, baseURL });

withCredentials: true 在发起跨域请i去的时候,后端已经开启CORS,前端需要也携带cookie,此时需要前端的请求头加上此配置,表示请求可以携带cookie。

封装get、post请求 export default{ get(opts) { return new Promise((resolve, reject) => { const params = { method: 'get' }; http(merge(params, opts)) .then(res => { // 这里就写业务逻辑请求时拿到的res,一般包含data、code、msg、res等 resolve(res); }) .catch(err => { reject(err); }); }); }, post(opts) { return new Promise((resolve, reject) => { const params = { method: 'post', headers: { 'Content-Type': 'application/json' } }; http(merge(params, opts)) .then(res => { // 这里就写业务逻辑请求时拿到的res,一般包含data、code、msg、res等 resolve(res); }) .catch(err => { reject(err); }); }); }, }

使用封装好的get、post去请求服务器:

// 普通get请求 function getComponentByIdentification(params) { return http.get({ url: `/web/system/getComponentByIdentification`, params }); } // get文件下载,此是需要在请求到接口后进行处理blob文件进行创建a标签进行下载 function downloadFile(params) { return http.get({ url: '/web/protocol/download', responseType: 'blob', params }); } // 普通post请求 function saveOrUpdateProtocol(params) { return http.post({ url: 'web/protocolManager/saveOrUpdateProtocol', data: params }); }

用法

// get、post请求写法 const param = { protocolBaseInfo: this.protocolBaseInfo }; getComponentByIdentification(param) .then(res => { // 写业务逻辑 }) // 不传参则直接写 getComponentByIdentification() .then(res => { // 写业务逻辑 }) 封装download下载请求,下载请求与get、post不同,需要兼容IE、以及判断下载的是哪种类型的文件。

以下代码对下载excel文件进行了封装,并且对下载失败的情况进行封装。

前端向服务端请求下载文件是以流的格式(stream)传递到前端,前端通常是将流转换为objectURL,借用a标签的download属性,进行文件下载。

文件下载失败时,服务端消息返回的文件格式不再是流,而是服务端返回的消息json(errorCode之类)对象,但是依然被包裹再 Blob 类型文件内,此时 blob 的 type 是text/json,前端虽然可以正常导出文件,但是文件内容是undefined。

值得注意的是

若是下载失败的情况,返回的类型是为 text/json,但是 IE 和 chrome 两者返回的不完全一样,如下:

IE 的 type 为 text/json;"

chrome 为 text/json

因此 若需要利用返回文件类型为 json 还是 stream,在响应拦截器内对错误状况作出处理时 ,判断文件类型时不能写入 res.type === 'text/json',需要写为 res.type.indexOf('json') > -1。

因此需要对文件内容进行解析

download(opts) { return new Promise((resolve, reject) => { let newParams = { method: 'get', responseType: 'blob' }; newParams = merge(newParams, opts); http(newParams) .then(res => { const blob = new Blob([res]); // 判断接收到的文件是否为json类型,是则需要作错误处理 if (res.type.indexOf('json') > -1) { var newblob = blob.slice(0, blob.size); // 需要对包裹在blob文件内部的json文件解析出来 var reader = new FileReader(); reader.readAsText(newblob, 'utf-8'); reader.onload = function(evt) { if (evt.target.readyState === FileReader.DONE) { const result = JSON.parse(evt.target.result); // 此时的result 和get、post接口一样返回的json对象内包含data、msg、code等,根据此 可在此处作出一些错误处理(弹出弹框等) } }; } else { // execl文件 const { params } = newParams; if (params.ext) params.type = params.ext; if (params.type === 'excel') params.type = 'xlsx'; const fileName = `${params.fileName}.${params.type}`; if ('download' in document.createElement('a')) { // 非IE下载 const elink = document.createElement('a'); elink.download = fileName; elink.style.display = 'none'; elink.href = URL.createObjectURL(blob); document.body.appendChild(elink); elink.click(); URL.revokeObjectURL(elink.href); // 释放URL 对象 document.body.removeChild(elink); } else { /** IE10+下载**/ navigator.msSaveBlob(blob, fileName); } } resolve(res); }) .catch(err => { reject(err); }); }); }

利用此进行文件下载:

// 文件下载,请求到数据后不需要进行任何处理,由封装好的download处理 function downloadFile(params) { return http.download({ url: '/web/protocol/download', params }); } 上传请求封装 upload(opts) { opts.url = `${opts.url}.do`; if (getToken() !== '') { opts.url += `?_csrf=${getToken()}`; } const axiosUpload = axios.create({ baseURL, timeout: timeOut, headers: { 'Content-Type': 'multipart/form-data', 'X-Requested-With': 'XMLHttpRequest' } }); // 响应拦截器 axiosUpload.interceptors.response.use(function(response) { // 对错误进行统一处理 return Promise.resolve(response.data); }); return new Promise((resolve, reject) => { axiosUpload .post(opts.url, opts.data) .then(res => { resolve(res); }) .catch(err => { reject(err); }); }); },

这里的'X-Requested-With': 'XMLHttpRequest'是让服务端知晓本次请求是ajax请求,看组件业务需求是否需要设置,公司业务是需要和单点登录对接跳转其他链接所用。

利用此进行上传文档

// 文档上传 function uploadFile(file) { return http.upload({ url: `/web/protocolFile/upload`, data: file }); } // 调用接口时 const form = new FormData(); // 文件对象 form.append('file', file); // 请求方法 uploadFile(form) .then(res => { // 写业务逻辑 }) 响应拦截

对于响应拦截,普通的get、post只需要根据错误码弹出错误框即可;但是对于上传、下载接口需要特殊处理。

http.interceptors.response.use( function(response) { // 请求文件流 使用get请求下载并且接口返回正常的情况 if (response.data.type === 'application/octet-stream') { // console.log('文件流'); return response; } // 拦截下载接口 如果下载接口使用get请求,需要判断是否为错误的状况 // 错误则需要将blob文件解析,然后赋值给response.data,可以接着走以下的错误处理逻辑 if (response.data.type && response.data.type.indexOf('json') > -1) { var reader = new FileReader(); reader.addEventListener('loadend', function(e) { response.data = JSON.parse(e.target.result); }); reader.readAsText(response.data); } // 对错误进行统一处理 if (response.data.code !== '0') { console.log('cuowule!!'); // 后台返回错误,可配合业务组件的一些信息作一些错误处理 } // response.data是接口请求完成后.then内拿到的真正的数据,不包含header等 return Promise.resolve(response.data); }, function(error) { const response = error.response; const rp = response.status; if (rp === 401 || rp === 403 || rp === 302) { if (process.env.NODE_ENV !== 'development') { window.location.reload(); } } else { if (error.message.indexOf('timeout') > -1) { // 超时判断,需要弹出超时的弹出框 } else { // 接口错误,做错误处理 } } // 对响应错误做点什么 return Promise.reject(error); } ); 请求拦截 // 请求拦截器 http.interceptors.request.use(function (config) { if (config.method === 'get') { config.url.indexOf('?') > '-1' ? config.url = config.url + '&_=' + Date.now() : config.url = config.url + '?_=' + Date.now() } return config }, function (error) { // 对请求错误做些什么 return Promise.reject(error) })


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3