NestJS调用Synology Upload API超时及FormData报错问题排查
NestJS调用Synology FileStation上传API超时及FormData报错排查
问题描述
使用NestJS调用Synology FileStation Upload API上传文件时,请求始终无响应直至超时。改用import * as FormData from 'form-data'并使用formData.getHeaders()时,执行formData.append('file', file)又触发source.on is not a function错误。以下是相关代码及超时响应信息,寻求问题排查方案。
代码示例
// Service import { HttpService } from '@nestjs/axios'; constructor(private readonly http: HttpService) {} async uploadFile(files: File[], file_path: string) { try { const formData = new FormData(); for (const file of files) { formData.append('file', file); } const data = await firstValueFrom( this.http .post(process.env.SYNOLOGY_URL, formData, { params: { api: 'SYNO.FileStation.Upload', version: 2, method: 'upload', _sid: this.sid, path: file_path, create_parents: false, overwrite: false, }, }) .pipe(map((response) => response.data)), ); } catch (error) { console.error(JSON.stringify(error, null, 2)); } }
超时响应信息
{ "message": "timeout of 10000ms exceeded", "name": "AxiosError", "stack": "AxiosError: timeout of 10000ms exceeded\n at RedirectableRequest.handleRequestTimeout (/usr/projects/backend/init_nestjs/node_modules/axios/lib/adapters/http.js:647:16)\n at RedirectableRequest.emit (node:events:518:28)\n at Timeout.<anonymous> (/usr/projects/backend/init_nestjs/node_modules/follow-redirects/index.js:210:12)\n at listOnTimeout (node:internal/timers:573:17)\n at processTimers (node:internal/timers:514:7)\n at Axios.request (/usr/projects/backend/init_nestjs/node_modules/axios/lib/core/Axios.js:45:41)", "config": { "transitional": { "silentJSONParsing": true, "forcedJSONParsing": true, "clarifyTimeoutError": false }, "adapter": [ "xhr", "http" ], "transformRequest": [ null ], "transformResponse": [ null ], "timeout": 10000, "xsrfCookieName": "XSRF-TOKEN", "xsrfHeaderName": "X-XSRF-TOKEN", "maxContentLength": -1, "maxBodyLength": -1, "env": {}, "headers": { "Accept": "application/json, text/plain, */*", "Content-Type": "multipart/form-data; boundary=axiosaxios-1.6.8-boundary-KyPk5XLtcOCa_vHTRUxIf-PRY", "User-Agent": "axios/1.6.8", "Content-Length": "263074", "Accept-Encoding": "gzip, compress, deflate, br" }, "maxRedirects": 5, "params": { "api": "SYNO.FileStation.Upload", "version": 2, "method": "upload", "_sid": "SYNOLOGY_SID", "path": "/docker", "create_parents": false, "overwrite": false }, "method": "post", "url": "SYNOLOGY_URL/webapi/entry.cgi", "data": {} }, "code": "ECONNABORTED", "status": null }
问题分析与解决方案
1. 请求超时问题
超时核心原因大概率是Axios自动生成的Content-Type头不符合Synology API要求,或请求参数/会话有效性存在问题:
- 手动指定FormData Headers:Axios自动生成的multipart边界可能无法被Synology正确解析,改用
form-data库的getHeaders()方法手动设置请求头 - 验证会话有效性:确认
_sid是当前有效会话ID,可通过Synology登录接口重新获取 - 调整超时时间:默认10s可能不足,适当调高至30s或更久
- 检查路径与权限:确认
path参数对应目录存在且当前_sid关联用户有上传权限,可尝试设置create_parents: true自动创建目录
2. source.on is not a function报错问题
该错误是因为form-data库的append方法不直接支持NestJS(multer)传入的File对象,需将文件转换为可读流或Buffer:
- 使用文件路径创建可读流(需确保multer配置了临时文件存储)
- 直接使用
file.buffer(multer会将文件内容读入Buffer)
修正后的完整代码
import { HttpService } from '@nestjs/axios'; import * as FormData from 'form-data'; import * as fs from 'fs'; import { firstValueFrom, map } from 'rxjs'; constructor(private readonly http: HttpService) {} async uploadFile(files: Express.Multer.File[], file_path: string) { try { const formData = new FormData(); for (const file of files) { // 方式1:使用可读流上传(需multer配置临时存储路径) formData.append('file', fs.createReadStream(file.path), { filename: file.originalname, }); // 方式2:直接使用Buffer上传 // formData.append('file', file.buffer, { filename: file.originalname }); } const data = await firstValueFrom( this.http .post(process.env.SYNOLOGY_URL, formData, { params: { api: 'SYNO.FileStation.Upload', version: 2, method: 'upload', _sid: this.sid, path: file_path, create_parents: true, // 自动创建不存在的父目录 overwrite: false, }, headers: { ...formData.getHeaders(), // 手动注入FormData的headers }, timeout: 30000, // 延长超时时间 }) .pipe(map((response) => response.data)), ); console.log('上传成功:', data); return data; } catch (error) { console.error('上传失败:', JSON.stringify(error, null, 2)); throw error; } }
额外注意事项
- 确认Synology设备与NestJS服务网络连通,防火墙未拦截5000/5001端口(默认Synology Web端口)
- 若使用HTTPS访问,需确保Synology的SSL证书被信任,或在Axios配置中关闭证书验证(仅测试环境使用)
- 批量上传时,检查Synology的文件大小限制,避免单文件或总大小超出限制
内容的提问来源于stack exchange,提问作者souldiary
相关产品推荐
相关产品推荐

