在节点中结合 multer 和 tinypng API

Combine multer and tinypng API in node

有人知道如何将 tinyPNG's API 与 multer 一起使用吗?文档看似简单:

var source = tinify.fromFile("unoptimized.jpg");
source.toFile("optimized.jpg");

虽然没有明确指示这是要去哪里,尤其是在像这样令人费解的事情中:

var storage =  multer.diskStorage(
    {
      destination: function (req, file, callback) {
        callback(null, './uploads');
      },

      filename: function (req, file, callback) {
        //use date to guarantee name uniqueness
        callback(null, file.originalname + '-' + Date.now());
      }
    }
);

//.any() allows multiple file uploads
var upload = multer({ storage : storage}).any()

app.post('/api/photo', function(req,res){

    upload(req,res,function(err) {

        if(err) {
            return res.end("Error uploading file.");
        }

        res.end("File is uploaded");
    });
});

我要"intercept" multer 上传的文件在哪里,以便我可以用 tinyPNG 压缩它?

在此先感谢您的帮助!

使用以下更改上传 photo/gallery 个文件的基本示例:

// Import express and multer.
var express = require('express');
var multer  = require('multer');

// Setup upload.
var upload = multer({ dest: 'uploads/' });
var multipleFiles = upload.fields([{ name: 'photo', maxCount: 1 }, 
                                   { name: 'gallery', maxCount: 8 }]);

// Setup tinify.
var tinify = require("tinify");
tinify.key = "YOUR_API_KEY";

// Get request handler for '/' path.
var app = express();
app.get('/', function (req, res) {
    res.setHeader("Content-Type", "text/html");
    res.end(
        "<form action='/api/photo' method='post' enctype='multipart/form-data'>" +
            "<input type='file' name='photo' />" +
            "<input type='file' name='gallery' multiple/>" +
            "<input type='submit' />" +
        "</form>"
    );
});

// Upload file handler with '/api/photo' path.
app.post('/api/photo', multipleFiles, function (req, res) {
    req.files['gallery'].forEach(function(file) {
       // Your logic with tinify here.
       var source = tinify.fromFile(file.path);
       source.toFile(file.path + "_optimized.jpg");
    });

    res.end("UPLOAD COMPLETED!");
});

随意更改 express 中间件,只需确保使用 upload.fields 并使用 tinify.key = "YOUR_API_KEY";

进行身份验证

我最近使用 tinify 包为自己解决了一个类似的问题,发现文档有些欠缺。

我有一个 Vue 前端,使用 vue2dropzone 收集用户上传的文件。这些被发送到节点/Express 后端。 我需要压缩文件并将其上传到 S3 实例而不存储在磁盘上。这意味着使用多个内存存储。 因此,将无法使用 tinify.fromFile(),因为本地没有存储文件。

在我的图像中间件中:

Const multer = require(“multer”);
const tinify = require("tinify");

tinify.key = "your_key";

exports.singleFile = multer({ storage: multer.memoryStorage() }).fields([{ name: "file", maxCount: 1 }]);

exports.uploadCompImage = async (req, res, next) => {
   try {
      const fileName = `${req.params.name}${path.extname(req.files.file[0].originalname)}`;
      const source = tinify.fromBuffer(req.files.file[0].buffer);
      source.store({
         service: "s3",
         aws_access_key_id: "your_id",
         aws_secret_access_key: "your_key
         region: "your_region",
         headers: {
            "Cache-Control": "public"
         },
         path: `your_bucket/your_folder/${fileName}`
      });
      return res.status(200).send(`path_to_file/${fileName}`)
   } catch (err) {
      console.log(err);
      next(err);
   }
}

然后在我的路由文件中:

Const images = require(“../middleware/images”);

// skipped several lines for brevity

productRouter
      .route("/images/:name")
      .post(images.singleFile, images.uploadCompImage)

此过程创建一个 multer singleFile 上传到 memoryStorage,使文件在 req.files.file[0] 可用(req.files[“file”] 因为我在 multer 中指定了“file”作为名称字段,如果上传多个则遍历此数组)。 设置好之后,我得到了文件名,通过使用 tinify 从 req.files.file[0].buffer 读取作为缓冲区来设置源。 然后我将源设置为我的 s3 实例并将 public link 发回文件。

希望这个回答对您有所帮助。我绝对可以看到通过更改 multer 选项更改过程以更改文件的位置,甚至将其写入磁盘。