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

Node.js中用Multer上传图片后,Imagemin压缩失败求助

Fixing Imagemin Compression Issues After Multer Upload

Let's break down the problems in your code and fix them step by step:

1. Imagemin is Asynchronous – You're Not Waiting for It to Finish

Imagemin returns a promise, but your current code doesn't handle it at all. This means the compression process might not complete before the request ends, and you're missing error feedback that could tell you what's wrong.

Fix with Promise Handling:

app.post('/upload', (req, res) => { 
  upload(req, res, (err) => { 
    if (err) { 
      res.render('picupload', { msg: err }); 
    } else { 
      if (req.file == undefined) { 
        res.render('picupload', { msg: 'Error: No File selected!' }); 
      } else { 
        console.log(req.file); 
        imagemin([`uploads/${req.file.filename}`], 'uploads/compressed', { 
          plugins: [ 
            imageminJpegtran(), 
            imageminPngquant({ quality: '65-80' }) // Fixed typo here
          ] 
        })
        .then(compressedFiles => {
          console.log('Compression complete:', compressedFiles);
          res.render('picupload', { 
            msg: 'File uploaded and compressed successfully!',
            file: `/uploads/compressed/${req.file.filename}`
          });
        })
        .catch(compressErr => {
          console.error('Compression failed:', compressErr);
          res.render('picupload', { msg: `Error compressing file: ${compressErr.message}` });
        }); 
      } 
    } 
  }); 
});

2. Invalid Quality Parameter in imageminPngquant

Your original code has quality: '65-80...' – the extra trailing dots are invalid syntax. Remove them to use the correct range format '65-80'.

3. Ensure the Output Directory Exists

Imagemin won't automatically create the uploads/compressed folder if it doesn't exist. Add code to check and create it before running compression:

First, require the filesystem module at the top of your file:

const fs = require('fs');

Then, add this before calling Imagemin:

const outputDir = 'uploads/compressed';
if (!fs.existsSync(outputDir)) {
  fs.mkdirSync(outputDir, { recursive: true });
}

4. Optional: Refactor to Async/Await for Cleaner Code

If you prefer a more readable approach, you can wrap the Multer callback in a promise and use async/await:

app.post('/upload', async (req, res) => { 
  try {
    // Wait for Multer to finish uploading
    await new Promise((resolve, reject) => {
      upload(req, res, (err) => err ? reject(err) : resolve());
    });

    if (!req.file) {
      return res.render('picupload', { msg: 'Error: No File selected!' });
    }

    console.log(req.file);

    // Create output directory if needed
    const outputDir = 'uploads/compressed';
    if (!fs.existsSync(outputDir)) {
      fs.mkdirSync(outputDir, { recursive: true });
    }

    // Run compression
    const compressedFiles = await imagemin(
      [`uploads/${req.file.filename}`], 
      outputDir, 
      { 
        plugins: [ 
          imageminJpegtran(), 
          imageminPngquant({ quality: '65-80' }) 
        ] 
      }
    );

    console.log('Compressed files:', compressedFiles);
    res.render('picupload', { 
      msg: 'File uploaded and compressed successfully!',
      file: `/uploads/compressed/${req.file.filename}`
    });

  } catch (err) {
    console.error('Process failed:', err);
    res.render('picupload', { msg: err.message });
  }
});

Quick Checks to Verify

  • Double-check you've installed all dependencies: npm install multer imagemin imagemin-jpegtran imagemin-pngquant
  • Confirm the original uploaded file exists in the uploads directory before compression runs
  • Check your console for error messages (the new catch blocks will log these now)

Content of the question is from Stack Exchange, question author roh_dev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:59:15