如何将Formidable的PersistentFile实例通过FormData与Fetch发送?
如何将Formidable的PersistentFile实例转换为可用于Fetch API FormData的文件对象
问题背景
基于Nuxt3/Nitro搭建API代理,通过Formidable接收文件后得到PersistentFile实例,直接传入FormData.append()时,Fetch API无法识别为文件类型。控制台输出的PersistentFile结构如下:
addImage.post.ts called with this content { photo: [ PersistentFile { _events: [Object: null prototype], _eventsCount: 1, _maxListeners: undefined, lastModifiedDate: 2023-01-07T22:33:43.127Z, filepath: '/tmp/0d0c99ee783bfe790d86da001', newFilename: '0d0c99ee783bfe790d86da001', originalFilename: 'Screenshot from 2023-01-04 09-04-32.png', mimetype: 'image/png', hashAlgorithm: false, size: 110657, _writeStream: [WriteStream], hash: null, [Symbol(kCapture)]: false } ] }
解决方案
在Nuxt3/Nitro的Node.js运行环境中,需将PersistentFile对应的本地临时文件转换为Blob、File或可读流,再添加到FormData中:
方法1:读取文件内容创建Blob/File对象(适合小文件)
import { readFile } from 'node:fs/promises'; import { Blob } from 'node:buffer'; export default defineEventHandler(async (event) => { const form = await readFormData(event); const persistentFile = form.get('photo')[0]; // 读取临时文件内容 const fileBuffer = await readFile(persistentFile.filepath); // 创建Blob对象 const blob = new Blob([fileBuffer], { type: persistentFile.mimetype }); // 可选:创建标准File对象 const file = new File([blob], persistentFile.originalFilename, { type: persistentFile.mimetype, lastModified: persistentFile.lastModifiedDate.getTime() }); // 构建FormData并发送请求 const targetFormData = new FormData(); targetFormData.append('photo', file, persistentFile.originalFilename); const response = await fetch('目标API地址', { method: 'POST', body: targetFormData }); return await response.json(); });
方法2:使用可读流(适合大文件,避免内存占用过高)
import { createReadStream } from 'node:fs'; export default defineEventHandler(async (event) => { const form = await readFormData(event); const persistentFile = form.get('photo')[0]; const targetFormData = new FormData(); // 传入临时文件的可读流,同时指定文件名和MIME类型 targetFormData.append('photo', createReadStream(persistentFile.filepath), { filename: persistentFile.originalFilename, type: persistentFile.mimetype }); const response = await fetch('目标API地址', { method: 'POST', body: targetFormData }); return await response.json(); });
核心说明
PersistentFile本质是存储在本地的临时文件,核心可用字段为filepath(临时文件路径)、originalFilename(原文件名)、mimetype(文件类型)。- Nuxt3/Nitro使用的Fetch API基于undici,其支持的FormData可直接接收
Blob、File或可读流,只需正确配置文件名和类型参数即可被识别为合法文件。
内容的提问来源于stack exchange,提问作者Bruno Lamps
相关产品推荐
相关产品推荐

