【问题标题】:Transform upload with NodeJS Multer使用 NodeJS Multer 转换上传
【发布时间】:2016-06-03 03:23:32
【问题描述】:

我目前正在为我的用户实施文件/图像上传服务。我想在上传到我的 s3 存储桶之前转换这些图像(调整大小/优化)。

我目前正在做的事情:在我的前端使用多部分表单(我认为这里的实际实现并不重要..)和我的后端的 multermulter-s3 包。

这里我的实现被剥离到了重要的部分。

// SETUP
var multer = require('multer');
var s3 = require('multer-s3');
var storage = s3({
    dirname: 'user/uploads',
    bucket: auth.aws.s3.bucket,
    secretAccessKey: auth.aws.s3.secretAccessKey,
    accessKeyId: auth.aws.s3.accessKeyId,
    region: auth.aws.s3.region,
    filename: function (req, file, cb) {
        cb(null, Date.now());
    }
});
var upload = multer({storage: storage}).single('img');

// ROUTE
module.exports = Router()
    .post('/', function (req, res, next) {
        upload(req, res, function (err) {
            if (err) {
                return res.status(401).json({err: '...'});
            }
            return res.json({err:null,url: '..'});
        });
    });

我想要做的:在上传之前转换图像。我不确定我是否需要在这里使用 multer/busboy 或者我可以使用 NodeJS 来完成(因此我也标记了 NodeJS 和 express)。

所以我的问题是:我可以在哪里拦截上传并在上传到我的 S3 存储桶之前对其进行转换?

【问题讨论】:

  • 好吧,您可以在上传到 S3 之前将文件保存在某个临时文件夹中吗?如果您不想将文件保存在内存中,则可以在内存中执行此操作,这取决于图像的大小,这种方法不适合较大的文件。
  • @RistoNovik 我可能可以做到这一点。但这听起来非常昂贵/不方便。
  • 您可以在前端转换图像,然后再将其发送到后端。
  • @AyoolaSolomon 没错,无论如何这将是调整大小的第一步,但您不应该只依赖前端。
  • @AyoolaSolomon 是的,不。我可以调整它的大小;但我无法想象我可以在前端完美地优化它。即使我可以: 不保证会完成;没有这些转换,有人可以POST 它,我想在任何情况下避免这种情况。

标签: node.js express multer busboy


【解决方案1】:

我尝试过使用@ItsGreg 的叉子,但无法让它工作。我设法通过使用multer-s3 标准配置和在我的文件上传端点内部使这种行为起作用,即,

app.post('/files/upload', upload.single('file'), (req, res) => {...})

我正在使用request 检索文件,并将缓冲区传递给sharp。以下工作(并假设您使用的是~/.aws/credentials):

    let request = require('request').defaults({ encoding: null });
    let dataURI = `https://s3.amazonaws.com/${process.env.AWS_S3_BUCKET}/${image.defaultUrl}`;
    request.get(dataURI, function (error, response, body) {
        if (! error && response.statusCode === 200) {
            let buffer = new Buffer(body);
            const sizes = ['thumbnail', 'medium', 'large'];
            sizes.forEach(size => {
                sharp(buffer)
                    .resize(image.sizes[size])
                    .toBuffer()
                    .then(data => {

                        // Upload the resized image Buffer to AWS S3.
                        let params = {
                            Body: data,
                            Bucket: process.env.AWS_S3_BUCKET,
                            Key: `${image.filePath}${image.names[size]}`,
                            ServerSideEncryption: "AES256",
                        };

                        s3.putObject(params, (err, data) => {
                            if (err) console.log(err, err.stack); // an error occurred
                            else console.log(data);           // successful response
                        });
                    })
            })
        }
    });

【讨论】:

    【解决方案2】:

    不确定您是否仍在寻找此问题的答案,但我遇到了同样的问题。我决定扩展multer-s3 包。

    我已经向original repository 发起了拉取请求,但现在,您可以使用my fork

    以下是如何使用扩展版本的示例:

      var upload = multer({
        storage: multerS3({
          s3: s3,
          bucket: 'some-bucket',
          shouldTransform: function (req, file, cb) {
            cb(null, /^image/i.test(file.mimetype))
          },
          transforms: [{
            id: 'original',
            key: function (req, file, cb) {
              cb(null, 'image-original.jpg')
            },
            transform: function (req, file, cb) {
              cb(null, sharp().jpg())
            }
          }, {
            id: 'thumbnail',
            key: function (req, file, cb) {
              cb(null, 'image-thumbnail.jpg')
            },
            transform: function (req, file, cb) {
              cb(null, sharp().resize(100, 100).jpg())
            }
          }]
        })
      })
    

    编辑:我的 fork 现在也可以通过 npm 以 multer-s3-transform 的名称获得。

    【讨论】:

    • 我正在使用此代码,但弹出此错误。 Cannot find name'sharp'.。我必须安装sharp npm 包还是这是内置的?
    • 你必须实现转换......在这个例子中,我使用了sharp,但你可以使用任何你想要的东西。
    • 你能提供完整的工作示例吗?我已经安装了sharp 包,但它给了我sharp(...).jpg is not a function 的错误
    • 我也有 sharp(...).jpg 不是功能问题。我解决它们的方法是我假设Sharp不再具有jpg功能。我改用了 .png() 函数,无论如何我实际上更喜欢 jpgs。如果您仍希望保留 jpg 格式,我建议您通过以下方式查看Sharp 的最新内容:npmjs.com/package/sharp
    • 对我来说它不起作用,没有错误发生,但文件没有上传,也没有进入这个函数。 var upload = multer({........}).single("file"); upload(req, res, function (err, filePath) { console.log(err, "Error"); console.log(filePath, "*************"); });
    猜你喜欢
    • 1970-01-01
    • 2018-07-21
    • 2017-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-16
    • 2017-10-09
    • 1970-01-01
    相关资源
    最近更新 更多