NestJS从数据库拉取大文件报错问题解决方案咨询
核心根因
你配置的body-parser仅负责解析客户端发送到服务端的入站请求体,完全不限制服务端返回给客户端的出站响应大小,所以调整body-parser参数无法解决拉取数据报错的问题。
首先先修正你现有代码的已知错误:
你的main入口配置存在两处语法错误,会导致之前配置的入站限制本身不生效,先修正:
import * as bodyParser from 'body-parser'; // 修正拼写错误与闭合缺失 app.use(bodyParser.json({ limit: '1.5gb' })); app.use(bodyParser.urlencoded({ limit: '1.5gb', extended: true, parameterLimit: 500000 }));
解决方案
优先选择分页方案(强推荐)
一次性返回GB级JSON数组本身不符合接口设计规范,会导致服务端内存占用飙升、传输耗时过长、客户端解析崩溃等问题,建议改为分页查询,实现示例如下:
控制器代码
@Get() async fetchByPage( @Query('page') page: number = 1, @Query('pageSize') pageSize: number = 100 ): Promise<{ data: Intro[], total: number }> { return this.sejourService.findByPage(page, pageSize); }
服务层代码
async findByPage(page: number, pageSize: number): Promise<{ data: Intro[], total: number }> { const skip = (page - 1) * pageSize; const [data, total] = await Promise.all([ this.introModel.find().skip(skip).limit(pageSize), this.introModel.countDocuments() ]); return { data, total }; }
必须全量返回的场景处理
如果业务确实要求全量返回数据,按以下顺序排查限制:
- 反向代理限制:如果使用Nginx、Apache等反向代理,默认会限制响应体大小,以Nginx为例,需要调整配置:
http { client_max_body_size 2G; proxy_max_temp_file_size 0; proxy_buffer_size 128k; proxy_buffers 4 256k; proxy_busy_buffers_size 256k; } - 中间件限制:检查是否添加了全局响应拦截、压缩等中间件,比如
compression中间件的阈值配置是否限制了大响应输出 - 前端请求库限制:比如axios默认有响应大小限制,需要调整配置:
const axiosInstance = axios.create({ maxContentLength: Infinity, maxBodyLength: Infinity });
文件返回特殊处理
如果接口返回的是二进制文件而非JSON数组,不要将文件全量读入内存后返回,使用流的方式传输避免内存溢出:
@Get('/download/:fileId') async download(@Param('fileId') fileId: string, @Res() res: Response) { const fileInfo = await this.fileService.getInfo(fileId); const readStream = fs.createReadStream(fileInfo.path); readStream.pipe(res); }
内容的提问来源于stack exchange,提问作者John Patrick Kokar
相关产品推荐
相关产品推荐

