You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 14:35:12