Node.js Express部署Render后FormData未定义及类型兼容问题求助
问题分析与解决方案
第一个错误:ReferenceError: FormData is not defined
原因很明确:你本地使用的Node.js版本应为v18及以上,该版本开始Node.js内置了浏览器端的FormData、Blob等API;但Render平台默认的Node.js版本可能低于v18,没有这些全局内置对象,因此部署后触发报错。
第二个错误:类型不兼容问题
你安装的form-data是Node.js环境下的第三方FormData实现,和浏览器/新版Node.js内置的FormData类型结构不同。新版Node.js的fetch API期望的BodyInit类型兼容内置FormData,但不兼容第三方form-data包的实例,因此出现类型匹配报错。
解决方案一:指定Render的Node.js版本为v18+(推荐)
这是最省心的方案,能和本地环境保持一致:
- 在
package.json中添加engines字段,明确指定Node.js版本:
{ "engines": { "node": ">=18.0.0" } }
- 在Render的项目设置中,确认Node.js版本选择与你指定的一致(或让Render自动读取package.json的配置)。
- 现有代码无需大幅修改——新版Node.js的
Blob支持Buffer作为参数,当前代码中new Blob([imageFile])的写法完全可行。
解决方案二:适配旧版Node.js(若无法升级版本)
如果必须使用低于v18的Node.js,需调整代码适配第三方包:
- 安装必要依赖:
npm install form-data node-fetch@2
(node-fetch@2为CommonJS版本,适配旧版Node.js,v3为ESM模块)
2. 修改代码:
import FormData from 'form-data'; import fetch from 'node-fetch'; export class PlanetNetDao extends AbstractDao{ readonly basicURL: string #API_KEY: string constructor(){ super() this.basicURL = 'https://my-api.plantnet.org' this.#API_KEY = process.env.PLANET_NET_API_KEY } async fetchIdentifyPlantPost(originalImageNames: string[]) { try { const formData = new FormData() for (let i = 0 ; i < originalImageNames.length ; i++) { const imageFile = this.fsReadFileSync(originalImageNames[i]) // 直接传入Buffer,无需Blob,form-data原生支持Buffer formData.append('images', imageFile, { filename: `image-${i}.jpg`, contentType: 'image/jpeg' }) this.removeImageFromStorage(originalImageNames[i]) } const response = await fetch (`${this.basicURL}/v2/identify/all?include-related-images=true&no-reject=false&lang=en&api-key=${this.#API_KEY}`, { method: 'POST', body: formData as unknown as BodyInit, // 类型断言解决类型不兼容问题 headers: formData.getHeaders() // 用form-data自动生成正确的multipart请求头 }) const res = await response.json() return res } catch (err) { console.log('Something went wrong, ' + err) throw err } } }
说明:
- 直接使用fs读取的Buffer传递给form-data,无需Blob(旧版Node.js无内置Blob)
- 调用
formData.getHeaders()自动生成包含边界符的Content-Type,避免手动设置出错 - 通过类型断言
as unknown as BodyInit绕过第三方FormData与BodyInit的类型校验
内容的提问来源于stack exchange,提问作者IdoBa
相关产品推荐
相关产品推荐

