Next.js 13 API Route结合ytdl-core实现YouTube下载器遇阻求助
解决Next.js + ytdl-core 视频下载响应问题
后端API路由修改(/api/download)
别写本地文件了,直接把ytdl的视频流转发给前端,同时设置正确的响应头,就能避免提前返回的问题:
import ytdl from 'ytdl-core'; import { NextApiRequest, NextApiResponse } from 'next'; export default async function handler(req: NextApiRequest, res: NextApiResponse) { const { url } = req.query; if (!url || typeof url !== 'string' || !ytdl.validateURL(url)) { return res.status(400).send('无效的YouTube链接'); } try { const info = await ytdl.getInfo(url); const format = ytdl.chooseFormat(info.formats, { quality: 'highest' }); // 设置响应头,让浏览器识别为可下载的视频文件 res.setHeader('Content-Disposition', `attachment; filename="${info.videoDetails.title}.${format.container}"`); res.setHeader('Content-Type', format.mimeType); // 直接把视频流pipe到响应对象,边下载边返回给前端 ytdl(url, { format }) .pipe(res) .on('error', () => { res.status(500).send('下载失败'); }); } catch (err) { res.status(500).send('获取视频信息失败'); } }
核心要点
- 取消本地文件写入操作,用
pipe直接转发流,不用等整个视频下载完再返回 - 提前设置
Content-Disposition和Content-Type,让浏览器知道这是要下载的视频 - 别在
finish事件里处理响应,pipe会自动管理响应流的结束,Next.js会在流完成后自动关闭响应
前端调用修改
前端点击按钮后,直接发起请求并触发浏览器下载,不用纠结Blob异常的问题:
const handleDownload = async (videoUrl) => { try { const res = await fetch(`/api/download?url=${encodeURIComponent(videoUrl)}`, { method: 'GET', }); if (!res.ok) throw new Error('下载请求失败'); // 创建临时下载链接 const blob = await res.blob(); const url = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; // 从响应头里拿文件名,没有就用默认名 const filename = res.headers.get('Content-Disposition')?.split('filename=')[1] || 'video.mp4'; a.download = filename.replace(/"/g, ''); document.body.appendChild(a); a.click(); // 清理临时资源 window.URL.revokeObjectURL(url); document.body.removeChild(a); } catch (err) { console.error(err); alert('下载失败,请检查链接是否有效'); } };
核心要点
- 用
encodeURIComponent处理视频链接,避免URL参数解析出错 - 直接通过
res.blob()获取视频流,创建下载链接让浏览器自动处理下载 - 从响应头提取文件名,保证下载的文件名和视频标题一致
常见问题排查
- 若仍出现Headers错误:检查API路由里有没有提前返回响应的逻辑(比如多余的
res.send()),确保只有pipe处理响应流 - 前端Blob size异常:说明后端返回的是错误信息而非视频流,检查视频链接验证和ytdl的错误捕获逻辑
- 跨域问题:Next.js本地开发默认同域无需配置,部署到平台时确保API路由没有跨域限制
内容的提问来源于stack exchange,提问作者Blake Doyle
相关产品推荐
相关产品推荐

