马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
背景:公司要求将 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[type="file"]');
- formData.append("file", fileInput.files[0]);
- // 添加文本字段
- 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 包
步骤 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: [data => data]
复制代码 - 兼容性查抄
- 假如使用 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[0]);
- 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企服之家,中国第一个企服评测及商务社交产业平台。 |