Node.js 文件上传处理:express + multer 踩坑记

项目里需要支持图片和附件上传,我选了 express + multer。看似简单,实际踩了好几个坑,整理出来供以后复盘。

1. multer diskStorage 与文件命名去重

默认 dest 会用随机十六进制字符串作为文件名,没有扩展名,前端不好预览。我改用 diskStorage,在 filename 回调里用 Date.now() 加原始扩展名重命名。同时为了避免高并发下时间戳重复,末尾再加一个三位随机数。

2. 大小 / 类型白名单校验

multer 本身有 limits 可以限制文件大小,但类型校验我放在 fileFilter 里。通过 file.mimetype 判断,只允许 image/jpeg、image/png、application/pdf 等几种。注意不能只看扩展名,要信任 mimetype;虽然 mimetype 也能伪造,但至少挡住了最基础的误上传。

3. static 托管上传目录

上传完成后,我希望能通过 URL 直接访问文件,于是用 app.use('/uploads', express.static(path.join(__dirname, 'uploads'))) 把目录挂出去。但这里有个细节:上传目录必须提前存在,否则 multer 会报错。我在启动脚本里加了 fs.mkdirSync('uploads', { recursive: true })。

4. 上传失败的前端错误提示

multer 遇到错误会调用 next(err),错误对象里没有中文提示。我在错误处理中间件里根据 err.code 做了映射:LIMIT_FILE_SIZE 提示文件过大,LIMIT_UNEXPECTED_FILE 提示字段名不对,其他错误统一提示上传失败。这样前端能给出明确反馈。

5. 目录权限问题

最坑的是生产环境。systemd 运行的用户不是 root,上传目录如果还是 root 权限就会写入失败。我通过 User=www-data 和 Group=www-data 指定运行用户,并把 uploads 目录 chown 给该用户。从此以后再也没有因为权限导致上传失败的问题。

← 返回首页