使用Next.js与Formidable上传文件至Supabase存储时文件不完整问题
问题分析与解决方案
你遇到的核心问题是:Supabase Storage的upload方法接收的是文件内容(Buffer/可读流)或本地文件路径,而你直接传入了Formidable解析后的文件对象,导致Supabase把这个对象的字符串表示上传,所以只有几十字节的无效内容。
修正代码方案
方案1:读取临时文件Buffer上传
先引入fs模块,读取Formidable保存的临时文件内容,再传给Supabase:
import fs from 'fs'; import formidable from 'formidable'; import { createClient } from '@supabase/supabase-js'; // 初始化Supabase客户端(根据你的配置调整) const supabase = createClient(process.env.NEXT_PUBLIC_SUPABASE_URL, process.env.SUPABASE_SERVICE_ROLE_KEY); export const config = { api: { bodyParser: false, // 必须禁用内置bodyParser,让Formidable处理 }, }; export default async function handler(req, res) { const form = new formidable.IncomingForm(); form.parse(req, async (err, fields, files) => { if (err) { console.error('Form解析错误:', err); return res.status(500).json({ error: '文件解析失败' }); } try { // 读取临时文件的Buffer内容 const fileBuffer = fs.readFileSync(files.image.filepath); const { data, error } = await supabase .storage .from('apg-bucket') .upload(files.image.originalFilename, fileBuffer, { contentType: files.image.mimetype, cacheControl: '3600', upsert: false, }); if (error) throw error; // 可选:删除Formidable生成的临时文件 fs.unlinkSync(files.image.filepath); res.status(200).json({ data, message: '文件上传成功' }); } catch (uploadErr) { console.error('Supabase上传错误:', uploadErr); res.status(500).json({ error: '文件上传失败' }); } }); }
方案2:直接传入临时文件路径
Supabase的upload方法支持直接传入本地文件路径(会自动读取文件),这种方式更简洁:
// 省略初始化代码,直接修改upload部分 const { data, error } = await supabase .storage .from('apg-bucket') .upload(files.image.originalFilename, files.image.filepath, { contentType: files.image.mimetype, cacheControl: '3600', upsert: false, });
关键说明
- Formidable解析文件后,会把文件保存到临时目录,
files.image.filepath是临时文件的绝对路径,files.image是包含文件元信息的对象,不能直接作为上传内容。 - 确保你的Next.js API路由禁用了内置的
bodyParser,否则Formidable无法正确解析请求。 - 上传完成后建议删除临时文件,避免服务器磁盘空间被占用。
内容的提问来源于stack exchange,提问作者DoIevenLift
相关产品推荐
相关产品推荐

