You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Fetch上传文件至Express服务器,Multer报Unexpected end of form错误

问题:Fetch上传文件配合Express+Multer失败的有效解决办法

此前已有用户提出过该问题,给出的解决方案为使用body-parser并将Multer降级至1.4.3,但这并非根本解决办法。我尝试使用Fetch上传文件,手动设置了boundary(不设置则会报错,但该boundary是从网上随意获取的,怀疑这可能是错误原因),目前请求失败,寻求有效解决方法。

前端代码

const file = fs.createReadStream(`${desktopDir}/ai2html-output/home-pro-Artboard_1.jpg`);
const title = "Test";

const form = new FormData();

form.append("title", title);
form.append("file", file);

const response = await fetch('https://example.com/uploads/1234', {
  method: 'POST',
  headers: {
        "Content-Type": "multipart/form-data; boundary=----WebKitFormBoundaryyEmKNDsBKjB7QEqu",
      },
  body: form 
});
const responseData = await response.json();

注:手动设置boundary是因为不设置会报错,但该boundary为网上随意获取。

服务器端Express配置

const multer = require('multer');
const upload = multer({ dest: '/var/www/vhosts/preview.inkto.art/httpdocs/html/' });

router.post('/uploads/:id', upload.single('file'), function(req, res) {
  const title = req.body.title;
  res.json({ msg: `file ${title} uploaded successfully!` });
});

服务器收到的请求头信息

:method: POST
:path: /uploads/1234
:scheme: https
accept: */*
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.9
content-length: 17
content-type: multipart/form-data; boundary=----WebKitFormBoundaryyEmKNDsBKjB7QEqu
origin: file://
sec-fetch-dest: empty
sec-fetch-mode: cors
sec-fetch-site: cross-site
user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 12_4_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36

解决办法

1. 移除手动设置的Content-Type头

当使用FormData作为fetch的body时,浏览器会自动生成包含正确boundary的Content-Type头。手动设置的boundary和FormData内部实际使用的不一致,会导致服务器无法解析表单数据,这是核心问题。

修改后的前端代码:

const file = fs.createReadStream(`${desktopDir}/ai2html-output/home-pro-Artboard_1.jpg`);
const title = "Test";

const form = new FormData();

form.append("title", title);
form.append("file", file);

const response = await fetch('https://example.com/uploads/1234', {
  method: 'POST',
  // 移除手动设置的Content-Type,让浏览器自动生成
  body: form 
});
const responseData = await response.json();

2. 配置服务器CORS规则

请求origin为file://,属于跨域请求,需确保Express服务器允许该来源的请求,或至少允许OPTIONS预检请求通过。可以使用cors中间件:

const cors = require('cors');
// 允许file://来源的请求
app.use(cors({ origin: 'file://' }));
// 开发环境可临时允许所有来源
// app.use(cors());

3. 检查文件流的有效性

确保文件路径正确、文件存在且有读取权限,可添加错误处理:

const fileStream = fs.createReadStream(`${desktopDir}/ai2html-output/home-pro-Artboard_1.jpg`);
fileStream.on('error', (err) => {
  console.error('读取文件失败:', err);
});
form.append("file", fileStream);

4. 完善Multer配置与错误捕获

确认Multer的dest目录存在且服务器有写入权限,同时添加错误捕获中间件:

router.post('/uploads/:id', upload.single('file'), function(req, res) {
  const title = req.body.title;
  res.json({ msg: `file ${title} uploaded successfully!` });
}, (err, req, res, next) => {
  // 捕获Multer上传错误
  res.status(400).json({ error: err.message });
});

内容的提问来源于stack exchange,提问作者FabricioG

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 08:12:27