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

NodeJS REST API实现图片持久化下载(避免新文件覆盖)

解决Node.js REST API下载图片时旧文件被覆盖的问题

问题背景

你在构建Node.js REST API实现从指定URL下载图片时遇到了一个头疼的问题:每次下载新图片时,之前保存的旧图片都会被覆盖,没办法保留所有下载的文件。

初始代码的问题根源

你最初的代码里,所有下载的图片都固定命名为model.jpg,这就导致每次新下载的文件都会直接替换掉之前同名的文件:

const express = require('express'); 
const app = express() 
const logger = require('morgan') 
const bodyParser= require('body-parser') 
const Fs = require ('fs'); 
const Path = require ('path'); 
const mongoose = require('mongoose'); 
const DB = require('./config/keys').MONGO_URI 
const Pictures = require('./model/pictureSchema'); 
const Axios = require ('axios'); 
const port = process.env.PORT || 4000; 

app.post('/download',async(req,res)=> { 
  const {img} = req.body 
  // console.log(req.body) 
  const url = img 
  const path = Path.join(__dirname, 'files', 'model.jpg') 
  const response = await Axios({ 
    method: 'GET', 
    url: url, 
    responseType: 'stream' 
  }) 
  response.data.pipe(Fs.createWriteStream(path)) 
  return new Promise ((resolve, reject) => { 
    response.data.on('end', ()=>{ 
      resolve() 
    }) 
    response.data.on('error', err =>{ 
      reject(err) 
    }) 
  }) 
})

修复思路

要解决这个问题,核心就是给每个下载的文件生成唯一的文件名,同时保留原图片的扩展名:

  • 从图片URL中提取文件扩展名,保证下载后的文件格式和原文件一致;
  • 使用UUID生成完全唯一的文件名前缀,彻底避免文件重名覆盖;
  • 补充参数校验和响应逻辑,给客户端明确的操作反馈。

修复后的代码

在@tadman的帮助下,修改后的代码完美解决了文件覆盖问题,同时增强了API的健壮性:

// 先执行 npm install uuid 安装依赖,再引入
const { v4: uuidv4 } = require('uuid');

app.post('/download',async(req, res)=> { 
  const {img} = req.body 
  const regex = new RegExp('[^.]+$') 
  const extension = img.match(regex); 

  if(!img){ 
    res.json({ message: 'please input a file link' }) 
  } else{ 
    const url = img 
    // 生成唯一文件名 + 原扩展名
    const path = Path.resolve(__dirname, 'files', `${uuidv4()}.${extension}`) 
    const response = await Axios({ 
      method: 'GET', 
      url: url, 
      responseType: 'stream' 
    }) 
    response.data.pipe(Fs.createWriteStream(path)) 
    return new Promise ((resolve, reject) => { 
      response.data.on('end', ()=>{ 
        resolve() 
        res.status(200).json({ message:'File download successfull' }) 
      }) 
      response.data.on('error', err =>{ 
        reject(err) 
        res.status(400).json({ message:'File download failed' }) 
      }) 
    }) 
  } 
})

关键优化点说明

  • 唯一文件名:uuidv4()会生成一个全球唯一的字符串作为文件名前缀,彻底杜绝了文件重名的可能;
  • 扩展名保留:通过正则匹配提取原URL中的文件扩展名,保证下载后的文件格式不丢失;
  • 逻辑完善:添加了图片URL的校验,避免空请求;同时在下载完成/失败时返回对应的状态码和提示信息,让客户端能清晰知道操作结果。

内容的提问来源于stack exchange,提问作者nAcademy Nigeria

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:03:26