export const addChart = (file, extraData = {}) => {
    const formData = new FormData()

    // 1️⃣ 添加文件(比如用户选择的图片、CSV、Excel 等)
    formData.append('file', file)

    // 2️⃣ 添加其他字段(如标题、描述、分类等)
    Object.keys(extraData).forEach((key) => {
        const value = extraData[key]
        if (value !== undefined && value !== null) {
            formData.append(key, value)
        }
    })

    return request({
        url: '/chart/gen',
        method: 'post',
        data: formData,
        // ⚠️ 注意:不要手动设置 Content-Type!
        transformRequest: [(data) => data], // 防止 Axios 把 FormData 转成 JSON
    })
}

🔑 关键点说明

特性

说明

FormData

浏览器原生 API,专用于构建 multipart/form-data 表单(支持文件 + 字段)

自动设置 Content-Type

✅ 不要手动写 'Content-Type': 'multipart/form-data'
因为浏览器会自动设置,并附带 boundary=----xxx
手动设置会丢失 boundary,导致后端解析失败!

transformRequest

告诉 Axios:“别把 formData 转成 JSON”,直接发送原始 FormData 对象

只传有效值

过滤掉 undefined / null,避免传无意义字段

🌰 使用示例

const file = e.target.files[0] // 用户选的图片
const extra = {
    title: '销售趋势图',
    chartType: 'line',
    userId: 123
}

addChart(file, extra)

⚠️ 常见错误

  • 手动设置 Content-Type: 'multipart/form-data'

→ ❌ 会丢失 boundary,后端无法解析

  • 忘记 transformRequest

→ Axios 默认会把对象 JSON.stringify,导致文件变成 [object File]

✅ 后端如何接收?(以 Spring Boot 为例)

@PostMapping("/chart/gen")
public Result genChart(
    @RequestParam("file") MultipartFile file,
    @RequestParam(value = "title", required = false) String title,
    @RequestParam(value = "chartType", required = false) String chartType
) {
    // 处理文件和参数
}

或用 DTO 接收(需配合 @ModelAttribute)。