You need to enable JavaScript to run this app. 前端FormData上传文件触发后端body-parser JSON解析报错的问题求解
优惠活动
大模型
产品
解决方案
定价
更多

前端FormData上传文件触发后端body-parser JSON解析报错的问题求解

错误根因定位
  • 报错本质是后端全局挂载的body-parser JSON解析中间件,无差别拦截了multipart/form-data格式的文件上传请求。
  • 前端通过FormData发起POST请求时,请求体开头是浏览器自动生成的multipart边界标识,格式为类似------WebKitFormBoundary7MA4YWxkTrZu0gW的字符串,第一个非空字符就是-。
  • 由于后端没有对不同Content-Type的请求做分流,所有进入路由的请求都被JSON解析中间件尝试执行JSON.parse(),碰到开头的-直接抛出语法错误,完全匹配提供的错误栈触发路径。
解决方案

调整后端中间件分流规则

JSON解析错误的核心诱因是中间件无差别拦截所有请求,需要做两项调整:

  • 修改全局JSON解析中间件的匹配规则,仅拦截Content-Type为application/json的普通接口请求,不对multipart请求做解析
  • 为媒体上传接口单独挂载multipart文件解析中间件,将其放在对应路由的处理链路最前面,确保multipart格式的请求不会流入JSON解析逻辑

参考正确的中间件挂载示例(匹配代码里通过req.files取文件的逻辑,对应express-fileupload组件):

// 错误的全局拦截写法(当前问题的来源)
// app.use(express.json());

// 正确配置
// 1. JSON解析仅匹配JSON类型请求
app.use(express.json({
  type: 'application/json'
}))

// 2. 上传路由单独挂载multipart解析组件
const fileUpload = require('express-fileupload');
app.use('/api/media', fileUpload(), mediaRouter);

修正前端服务配置

当前前端服务代码中手动设置了空的请求头对象,需要调整:

  • 上传FormData时禁止手动设置Content-Type: multipart/form-data,否则浏览器不会自动填充请求所需的boundary参数,会引发新的解析错误
  • 直接移除手动设置的空HttpHeaders实例,让浏览器自动为FormData请求配置正确的请求头:
public saveAWS(data: FormData): Observable<any> {
  return this.http.post('http://localhost:5007/api/media', data);
}

修复后端业务逻辑的隐藏Bug

解决JSON解析报错后,以下代码问题会继续导致上传流程异常:

  • 路由定义笔误:后端路由中router.route('http://localhost:5007/api/media')的写法不符合Express规范,路由仅支持相对路径定义,正确写法为router.route('/media'),由上层应用挂载时统一配置全局路径前缀(如app.use('/api', mediaRouter))。
  • 字段校验拼写错误:校验path字段时的错误提示误写为"El campo patch esta vacio",需修正为对应path字段的提示。
  • 错误的文件读取逻辑:Node后端环境不存在前端式的FileReaderAPI,代码中通过new FileReader()读取文件的写法无法正常执行。express-fileupload组件拿到的文件对象本身就携带文件buffer,可直接作为S3上传的入参Body,无需额外读取:
    const fileName = moment().unix().toString() + '_' + file.name;
    const params = {
      Bucket: config.s3.bucket,
      Body: file.data, // 直接使用文件buffer替代FileReader读取的结果
      Key: `${path}/${fileName}`,
      ContentType: file.mimetype,
      ACL: 'public-read'
    }
    
  • 无意义的异步操作:代码中data["url"] = await url的写法冗余,url是手动拼接的静态字符串,不需要异步等待。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.02 12:15:05