Fastify集成BusBoy上传文件报Unsupported Media Type错误求助
解决Fastify中使用BusBoy上传文件时的415 Unsupported Media Type错误
错误原因
Fastify默认未配置multipart/form-data类型的请求解析器,当收到该类型请求时会直接返回415错误。同时你的代码存在几处逻辑问题需要调整。
解决方案
1. 禁用Fastify自动解析请求体
在路由配置中添加parse: false,阻止Fastify自动解析请求体,让BusBoy直接处理原始请求流:
const postOpts = { parse: false, // 关键:禁用自动解析 schema: { summary: "Upload File", contentType: 'multipart/form-data', // Fastify v4推荐用contentType替代废弃的consumes response: { 201: { // 对应实际返回的201状态码 type: "object", description: "文件上传成功", properties: { statusCode: { type: "number" }, uploadConfirmed: { type: "boolean" } }, }, 400: { type: "object", description: "请求无效或文件不符合要求", properties: { error: { type: "string" }, statusCode: { type: "number" }, message: { type: "string" }, }, }, 500: { type: "object", description: "服务器内部错误", properties: { error: { type: "string" }, statusCode: { type: "number" }, message: { type: "string" }, }, }, }, } as const, };
2. 修正BusBoy的使用逻辑
- 将
request.pipe(bb)移到事件绑定之外,确保请求流被及时捕获 - 用Promise包裹异步处理逻辑,等待文件上传完成再返回响应
- 补充错误处理,避免请求挂起
修改后的路由处理函数:
import Busboy from "busboy"; async function uploadFile(fastify: any, _options: Object) { fastify.post( "/v1/uploads/uploadFile", postOpts, async function (request: any, reply: any) { return new Promise((resolve, reject) => { const bb = Busboy({ headers: request.headers, preservePath: true, limits: { fileSize: 100000 }, }); // 处理文件流 bb.on("file", (fieldname, file, filename, encoding, mimetype) => { console.log(`收到文件:${filename},字段名:${fieldname}`); // 这里可添加文件存储逻辑,比如写入磁盘或云存储 file.on('data', (chunk) => { // 处理文件数据块 }); file.on('end', () => { console.log(`文件 ${filename} 接收完成`); }); file.on('error', (err) => { reject(new Error(`文件处理失败:${err.message}`)); }); }); // 上传完成后返回响应 bb.on("finish", () => { resolve( reply .code(201) .header("Server-Timing", createServerTiming(serverTiming)) .header("Content-Type", "application/json; charset=utf-8") .send({ statusCode: 201, uploadConfirmed: true }) ); }); // 捕获BusBoy错误 bb.on("error", (err) => { reply.code(400).send({ error: err.message, statusCode: 400, message: "文件上传失败" }); reject(err); }); // 将请求流导入BusBoy request.pipe(bb); }); } ); }
关键注意点
- Fastify v4已废弃
consumes字段,改用contentType指定请求类型 - BusBoy的处理是异步的,必须用Promise包裹,确保Fastify等待处理完成再响应
- 务必处理文件流和BusBoy的错误事件,避免出现未捕获异常导致请求挂起
内容的提问来源于stack exchange,提问作者Bill
相关产品推荐
相关产品推荐

