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]