Next.js 15 Route Handlers 流式上传与断点续传概述Route Handlers 支持 `runtime='edge'`,使用 `ReadableStream` 读取请求体并与对象存储协作,实现大文件的分片上传与断点续传。流式上传(边缘)// app/api/upload/route.ts export const runtime = 'edge' export async function POST(req: Request) { const contentType = req.headers.get('content-type') || '' if (contentType.startsWith('multipart/form-data')) { // 边缘不支持 Node 的 multipart 解析库;改用前端分片 + 原始流 return new Response(JSON.stringify({ error: 'Use chunked upload' }), { status: 400 }) } const range = req.headers.get('content-range') // e.g., bytes 0-1048575/2097152 const key = req.headers.get('x-upload-key') || crypto.randomUUID() const body = req.body as ReadableStream // 将流直接转发到对象存储(伪代码) await forwardToStorage(key, body, range) return new Response(JSON.stringify({ ok: true, key }), { status: 200 }) } 客户端分片与续传export async function uploadChunk(url: string, key: string, chunk: ArrayBuffer, start: number, end: number, total: number) { const res = await fetch(url, { method: 'POST', headers: { 'Content-Range': `bytes ${start}-${end}/${total}`, 'x-upload-key': key, 'Content-Type': 'application/octet-stream' }, body: new Blob([chunk]) }) return res.ok } 断点续传状态查询// app/api/upload/status/route.ts export const runtime = 'edge' export async function GET(req: Request) { const key = new URL(req.url).searchParams.get('key') const offset = await getUploadedOffset(key!) return new Response(JSON.stringify({ key, offset }), { status: 200 }) } 技术参数与验证浏览器:Chrome 120+;边缘:Vercel Edge/Cloudflare Workers大文件分片:1-8MB;失败重试与续传可靠;服务器内存占用可控注意事项边缘运行时不支持 Node-only 库;尽量用原生流与外部存储 API校验哈希与范围;完成后合并对象并验证完整性常见问题Q: multipart 表单能用吗?A: 边缘不建议;推荐分片 + 原始流。参考资料Next.js Route Handlers 文档;对象存储直传与断点续传实践。---发布信息:已发布 · 技术验证 · 阅读 40 分钟 · CC BY-SA 4.0

发表评论 取消回复