SpringBoo和vue项目blob传参未生效

学无止境,气有浩然

文章目录


前言

工作里做的一个小工具,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 = href
    let 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_url
    timeout: 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 = 0
    try {
    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.data
    if (errorMsg !== undefined) {
    Notification.error({
    title: errorMsg,
    duration: 3000
    })
    } else {
    Notification.error({
    title: '未知错误',
    duration: 3000
    })
    }
    } else {
    const errorMsg = error.response.data.message
    if (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,导致接收不到请求。


解决

就是判断一下请求里面是否设置了请求头就好了。

java 复制代码
if (!config.headers['Content-Type']) {
  config.headers['Content-Type'] = 'application/json'
}

打完收工!

相关推荐
过客随尘1 小时前
Spring AOP以及事务详解(一)
spring boot·后端
vx_dmxq2111 小时前
【微信小程序学习交流平台】(免费领源码+演示录像)|可做计算机毕设Java、Python、PHP、小程序APP、C#、爬虫大数据、单片机、文案
java·spring boot·python·mysql·微信小程序·小程序·idea
q***07141 小时前
Spring Boot 中使用 @Transactional 注解配置事务管理
数据库·spring boot·sql
是一碗螺丝粉1 小时前
React Native 运行时深度解析
前端·react native·react.js
Jing_Rainbow1 小时前
【前端三剑客-9 /Lesson17(2025-11-01)】CSS 盒子模型详解:从标准盒模型到怪异(IE)盒模型📦
前端·css·前端框架
爱泡脚的鸡腿1 小时前
uni-app D6 实战(小兔鲜)
前端·vue.js
青年优品前端团队2 小时前
🚀 不仅是工具库,更是国内前端开发的“瑞士军刀” —— @qnvip/core
前端
北极糊的狐2 小时前
Vue3 中父子组件传参是组件通信的核心场景,需遵循「父传子靠 Props,子传父靠自定义事件」的原则,以下是资料总结
前端·javascript·vue.js
看到我请叫我铁锤2 小时前
vue3中THINGJS初始化步骤
前端·javascript·vue.js·3d
q***25212 小时前
SpringMVC 请求参数接收
前端·javascript·算法