Node.js 18环境下@nestjs/axios的HttpService无法正常工作
问题排查与解决方案
1. 修正FormData导入方式
把动态require的写法换成静态import,避免Node.js 18下的模块加载异常:
import FormData from 'form-data';
替换原代码里的const FormData = require('form-data');
2. 手动设置FormData请求头
Node.js 18下,axios可能无法自动识别FormData并生成带boundary的Content-Type头,需要手动获取并传递:
// 在发送请求时添加headers配置 this.httpService.post(process.env.PYPDF.concat('html_pdf'), bodyFormData, { headers: bodyFormData.getHeaders(), })
3. 修复错误处理的边界判断
原代码直接访问e.response.data,当请求因网络问题、服务端无响应等情况时,e.response会是undefined,导致报错。必须先做存在性检查:
catchError((e) => { const errorMessage = e.response?.data || e.message || '未知错误'; const statusCode = e.response?.status || 500; throw new HttpException(errorMessage, statusCode); }),
4. 确保依赖版本兼容
Node.js 18对axios的新版本支持更好,更新@nestjs/axios和axios到兼容版本:
npm update @nestjs/axios axios
建议使用axios >= 1.3.0版本,该版本修复了Node.js 18下FormData的处理问题。
5. 安全构造FormData
避免空值或无效数据导致请求异常,添加属性存在性检查:
for (const key in body) { if (body.hasOwnProperty(key) && body[key] != null) { bodyFormData.append(key, body[key]); } }
完整修改后的代码
import { HttpException, Injectable } from '@nestjs/common'; import { HttpService } from '@nestjs/axios'; import { lastValueFrom, catchError, map } from 'rxjs'; import { AdjuntoService } from '../adjunto/adjunto.service'; import { HtmlPdfBodyPost, HtmlPdfBodyQueryPost } from 'src/dtos/aux.dto'; import { CierreContableService } from '../cierre_contable/cierre_contable.service'; import FormData from 'form-data'; @Injectable() export class FilesService { constructor( private readonly httpService: HttpService, private readonly adjunto: AdjuntoService, private readonly cierreContable: CierreContableService, ) {} async htmlToPdf(query: HtmlPdfBodyQueryPost, body: HtmlPdfBodyPost) { const bodyFormData: FormData = new FormData(); for (const key in body) { if (body.hasOwnProperty(key) && body[key] != null) { bodyFormData.append(key, body[key]); } } const data = await lastValueFrom( this.httpService .post(process.env.PYPDF.concat('html_pdf'), bodyFormData, { headers: bodyFormData.getHeaders(), }) .pipe( map((resp) => resp.data), catchError((e) => { const errorMessage = e.response?.data || e.message || '未知错误'; const statusCode = e.response?.status || 500; throw new HttpException(errorMessage, statusCode); }), ), ); return { data }; } }
内容的提问来源于stack exchange,提问作者MML1357
相关产品推荐
相关产品推荐

