用户云卷云舒 发表于 2025-3-13 17:50:47

axios升级1.7.4时,FormData方式请求报错

背景:公司要求将 axios 从 0.18.0 升级到 1.7.4 。然而升级过程中发现,FormData 请求报错。
经排查,axios 1.X版本有很大的改变。这个报错大概是由于新版 axios 对 FormData 的处理逻辑和请求头配置的调解导致的。
标题根源分析


[*] Content-Type 头的手动覆盖
新版 axios 会自动为 FormData 类型的数据设置 Content-Type: multipart/form-data; boundary=...,但假如你手动设置了 Content-Type,会导致丢失 boundary 参数,服务器无法解析请求体。
[*] FormData 实例的严酷校验
axios@1.x 对 FormData 的校验更严酷,要求数据必须是浏览器原生的 FormData 实例(或 Node.js 的 form-data 包实例),不再支持旧版的普通对象。
[*] Node.js 环境的兼容性
在 Node.js 中,必须使用 form-data 库生成 FormData,并手动设置正确的请求头。
解决方案

1. 浏览器环境

步骤 1:移除手动设置的 Content-Type 头
// 错误写法(手动覆盖 Content-Type)
axios.post("/upload", formData, {
headers: {
    "Content-Type": "multipart/form-data", // ❌ 删除此行
},
});

// 正确写法(由 axios 自动设置)
axios.post("/upload", formData); // ✅
步骤 2:确保正确创建 FormData 对象
// 创建 FormData 实例
const formData = new FormData();

// 添加文件字段
const fileInput = document.querySelector('input');
formData.append("file", fileInput.files);

// 添加文本字段
formData.append("name", "file-upload");

// 发送请求
axios.post("/upload", formData)
.then((res) => console.log(res.data))
.catch((err) => console.error("Error:", err));
2. Node.js 环境

步骤 1:安装 form-data 包
npm install form-data
步骤 2:生成并配置 FormData
const FormData = require("form-data");
const axios = require("axios");
const fs = require("fs");

// 创建 FormData 实例
const formData = new FormData();

// 添加文件(Stream 或 Buffer)
formData.append("file", fs.createReadStream("./test.jpg"));

// 添加文本字段
formData.append("text", "Hello from Node.js");

// 发送请求时携带 headers(必须包含 formData 的 headers)
axios.post("http://example.com/upload", formData, {
headers: {
    ...formData.getHeaders(), // ✅ 获取正确的 Content-Type 和 boundary
},
})
.then((res) => console.log(res.data))
.catch((err) => console.error("Error:", err.message));
常见错误及修复

错误 1:Missing boundary in Content-Type



[*]原因:手动设置了 Content-Type: multipart/form-data,导致丢失 boundary。
[*]修复:删除手动设置的 Content-Type 头。
错误 2:Request body is not a FormData instance



[*]原因:转达的数据不是 FormData 实例。
[*]修复:查抄数据是否通过 new FormData() 创建。
错误 3:Unexpected end of form data(Node.js)



[*]原因:未正确设置请求头。
[*]修复:在 Node.js 中调用 formData.getHeaders() 获取完整头信息。
验证代码是否兼容

在代码中添加以下查抄:
// 检查是否为合法的 FormData 实例
if (!(formData instanceof FormData)) {
throw new Error("Data must be a FormData instance!");
}

// 检查请求头是否包含 boundary
console.log(formData.getHeaders()); // Node.js 中应输出类似 { "content-type": "multipart/form-data; boundary=..." }
迁移注意事项


[*] 避免使用 transformRequest
新版 axios 默认会正确处理 FormData,无需自界说 transformRequest。
// 旧版可能存在的配置(需删除)
transformRequest:

[*] 兼容性查抄

[*]假如使用 axios.interceptors,确保拦截器未修改 Content-Type。
[*]在浏览器中,确保没有第三方库(如 qs)意外修改 FormData。

[*] 测试边界场景

[*]上传大文件(>10MB)。
[*]混合上传文件和文本字段。

完整示例代码

浏览器端

<input type="file" id="fileInput" />
<button onclick="upload()">Upload</button>

<script src="https://cdn.jsdelivr.net/npm/axios@1.7.4/dist/axios.min.js"></script>
<script>
async function upload() {
    const fileInput = document.getElementById("fileInput");
    const formData = new FormData();
    formData.append("file", fileInput.files);
    formData.append("comment", "Uploaded via axios 1.7.4");

    try {
      const res = await axios.post("/upload", formData);
      console.log("Success:", res.data);
    } catch (err) {
      console.error("Error:", err.message);
    }
}
</script>
Node.js 端

const FormData = require("form-data");
const axios = require("axios");
const fs = require("fs");

async function uploadFile() {
const formData = new FormData();
formData.append("file", fs.createReadStream("./test.jpg"));
formData.append("text", "Node.js upload");

try {
    const res = await axios.post("http://example.com/upload", formData, {
      headers: formData.getHeaders(),
    });
    console.log("Success:", res.data);
} catch (err) {
    console.error("Error:", err.message);
}
}

uploadFile();
通过以上调解,可确保 FormData 请求在 axios@1.7.4 中正常工作。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: axios升级1.7.4时,FormData方式请求报错