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

Next.js后端API实现URL自动下载文件方案问询

实现Next.js API端的远程文件下载函数

完全可以实现你需要的download函数,以下是两种适配Next.js API路由场景的可行方案:

方案一:原生Node.js实现(无第三方依赖)

利用Node.js内置模块完成远程请求与文件写入,无需额外安装依赖:

import { createWriteStream, promises as fs } from 'fs';
import { promisify } from 'util';
import { pipeline } from 'stream';
import http from 'http';
import https from 'https';
import { parse } from 'url';
import path from 'path';

const streamPipeline = promisify(pipeline);

async function download(url, outputPath) {
  const { protocol } = parse(url);
  const client = protocol === 'https:' ? https : http;

  return new Promise((resolve, reject) => {
    client.get(url, async (response) => {
      if (response.statusCode !== 200) {
        reject(new Error(`请求失败,状态码:${response.statusCode}`));
        return;
      }

      try {
        // 自动创建不存在的目录
        const dir = path.dirname(outputPath);
        await fs.mkdir(dir, { recursive: true });
        
        await streamPipeline(response, createWriteStream(outputPath));
        resolve();
      } catch (err) {
        reject(err);
      }
    }).on('error', reject);
  });
}

export default async function handler(req, res) {
  if (req.method === 'POST') {
    try {
      // 用绝对路径避免Next.js环境下的路径问题
      const outputPath = path.join(process.cwd(), 'downloads', 'file');
      await download(req.body.url, outputPath);
      res.status(200).json({ success: true, message: '文件下载完成' });
    } catch (err) {
      res.status(500).json({ success: false, error: err.message });
    }
  } else {
    res.setHeader('Allow', ['POST']);
    res.status(405).end(`Method ${req.method} Not Allowed`);
  }
}

方案二:使用第三方工具包(更简洁)

推荐两种常用的第三方工具实现方式:

1. 使用download包(专门针对文件下载场景)

先安装依赖:

npm install download

实现代码:

import download from 'download';
import path from 'path';

export default async function handler(req, res) {
  if (req.method === 'POST') {
    try {
      const outputDir = path.join(process.cwd(), 'downloads');
      // 自动处理文件写入与目录创建
      await download(req.body.url, outputDir);
      res.status(200).json({ success: true, message: '文件下载完成' });
    } catch (err) {
      res.status(500).json({ success: false, error: err.message });
    }
  } else {
    res.setHeader('Allow', ['POST']);
    res.status(405).end(`Method ${req.method} Not Allowed`);
  }
}

2. 使用axios配合文件流

先安装依赖:

npm install axios

实现代码:

import axios from 'axios';
import { createWriteStream, promises as fs } from 'fs';
import { promisify } from 'util';
import { pipeline } from 'stream';
import path from 'path';

const streamPipeline = promisify(pipeline);

async function download(url, outputPath) {
  const response = await axios({
    url,
    method: 'GET',
    responseType: 'stream'
  });

  const dir = path.dirname(outputPath);
  await fs.mkdir(dir, { recursive: true });
  
  await streamPipeline(response.data, createWriteStream(outputPath));
}

export default async function handler(req, res) {
  if (req.method === 'POST') {
    try {
      const outputPath = path.join(process.cwd(), 'downloads', 'file');
      await download(req.body.url, outputPath);
      res.status(200).json({ success: true, message: '文件下载完成' });
    } catch (err) {
      res.status(500).json({ success: false, error: err.message });
    }
  } else {
    res.setHeader('Allow', ['POST']);
    res.status(405).end(`Method ${req.method} Not Allowed`);
  }
}

注意事项

  • 确保downloads目录具备写入权限,部署环境中需提前配置文件系统权限
  • 始终使用绝对路径(结合process.cwd()),避免Next.js开发/生产环境的路径差异
  • 所有方案均自动适配http/https协议的远程文件URL
  • 保留错误捕获逻辑,返回明确的错误信息给请求端

内容的提问来源于stack exchange,提问作者venkata avinash appala

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 16:27:37