NodeJS REST API实现图片持久化下载:避免新图覆盖旧图
解决Node.js REST API下载图片时覆盖旧文件的问题
问题核心
你遇到的问题很典型:每次通过API下载新图片时,旧图片都会被自动覆盖——根源在于初始代码里固定使用了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) }) }) })
修复思路
要保留所有下载的图片,核心是给每个文件生成唯一的文件名,同时保留原图片的扩展名保证格式正确:
- 用
uuidv4()生成全局唯一标识符(需先安装uuid包) - 从图片URL中提取原文件的扩展名
- 将唯一ID和扩展名组合成新文件名,彻底避免重复
修复后的代码
// 先安装uuid包: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' }) }) }) } })
额外优化提示
- 可以改进扩展名提取逻辑:用
path.extname(new URL(img).pathname).slice(1)替代正则,能更准确处理包含多个.的URL(比如https://example.com/image.v2.jpg) - 建议给异步操作添加
try/catch捕获错误,避免未处理的Promise rejection
内容的提问来源于stack exchange,提问作者nAcademy Nigeria
相关产品推荐
相关产品推荐

