学无止境,气有浩然
文章目录
- 前言
- 展示问题代码
- 问题
- 解决
- 打完收工!
前言
工作里做的一个小工具,axios
传参,使用FormData
传参到后端,没有办法映射除字段值,但是从控制台看,传的字段值都是正确的,当然开始是因为简单没有将axios
抽调公共组件,由于抽调出来之后开始报这个错误,那么很明显就是这个问题导致了。
展示问题代码
- 请求部分
handleFileUpload(file) {const formData = new FormData()if (file) {formData.append('file', file.file)}formData.append('name', this.form.name)formData.append('num', this.form.num)formData.append('env', this.form.env)formData.append('nameGenMethod', this.form.nameGenMethod)request.post('/home/test', formData, {responseType: 'blob',headers: {'Content-Type': 'multipart/form-data'}}).then(response => {this.filedownload(response)this.$message({message: 'handle success',type: 'success'})}).catch(error => {const decoder = new TextDecoder('utf-8');this.$message({message: decoder.decode(error.response.data),type: 'error'})})},filedownload (res) {const filename = res.headers['content-disposition']// const blob = new Blob([ iconv.decode(res.data, 'GBK')])const blob = new Blob([ res.data])var downloadElement = document.createElement('a')var href = window.URL.createObjectURL(blob)downloadElement.href = hreflet finalfilename = filename.split('filename=')[1]if (finalfilename.startsWith('"')) {finalfilename = finalfilename.substring(1)}if (finalfilename.endsWith('"')) {finalfilename = finalfilename.substring(0, finalfilename.length - 1)}downloadElement.download = decodeURIComponent(finalfilename)document.body.appendChild(downloadElement)downloadElement.click()document.body.removeChild(downloadElement)window.URL.revokeObjectURL(href)}}
- 公共部分
import axios from 'axios'
import { Notification } from 'element-ui'// 创建axios实例
const service = axios.create({baseURL: process.env.NODE_ENV === 'production' ? process.env.VUE_APP_BASE_API : '/', // api 的 base_urltimeout: 3000000 // 请求超时时间
})function getToken () {let accessToken = sessionStorage.getItem("access_token")if (accessToken) {return 'Bearer ' + accessToken}return false
}
// request拦截器
service.interceptors.request.use(config => {if (getToken()) {config.headers.Authorization = getToken() // 让每个请求携带自定义token 请根据实际情况自行修改}config.headers['Content-Type'] = 'application/json'return config},error => {Promise.reject(error)}
)// response 拦截器
service.interceptors.response.use(response => {if (response.data instanceof Blob) {return response}return response.data},error => {if (error.toString().indexOf('Error: timeout') !== -1) {Notification.error({title: '网络请求超时',duration: 300000})return Promise.reject(error)}// 兼容blob下载出错json提示if (error.response.data instanceof Blob) {error.response.data.text().then(res => {Notification.error({title: res,duration: 3000})})} else {let code = 0try {code = error.response.status} catch (e) {if (error.toString().indexOf('Error: timeout') !== -1) {Notification.error({title: '网络请求超时',duration: 3000})return Promise.reject(error)}}if (code) {if (code === 401) {Notification.warning({title: '未认证',duration: 3000})sessionStorage.removeItem("access_token")} else if (code === 403) {Notification.warning({title: '未认证',duration: 3000})sessionStorage.removeItem("access_token")} else if (code === 500) {const errorMsg = error.response.dataif (errorMsg !== undefined) {Notification.error({title: errorMsg,duration: 3000})} else {Notification.error({title: '未知错误',duration: 3000})}} else {const errorMsg = error.response.data.messageif (errorMsg !== undefined) {Notification.error({title: errorMsg,duration: 5000})} else {Notification.error({title: '未知错误',duration: 3000})}}} else {Notification.error({title: '远程服务器断开连接',duration: 3000})}}return Promise.reject(error)}
)
export default service
因为项目可能会传文件,虽然不是必选项,但是可以通用,所以
axios
传输的时候可以使用multipart/form-data
的请求头。
问题
在抽取公共请求代码的时候,重新设置了请求头为application/json
,就导致使用js
提供的FormData
无法解析成为json
,导致接收不到请求。
解决
就是判断一下请求里面是否设置了请求头就好了。
if (!config.headers['Content-Type']) {config.headers['Content-Type'] = 'application/json'
}