在NodeJS中读取文件的有效方法

时间:2017-11-02 15:37:57

标签: node.js express fs

我收到了从Ajax请求发送的图像文件:

var data = canvas.toDataURL('image/jpg', 1.0);
$.post({
  url: "/upload-image",
  data: { 
    file: data
  }
}).done(function(response) {
  ....
})

}

在服务器端,我想将图像文件传输到API

function getOptions(buffer) {
  return {
    url: '.../face_detection',
    headers: headers,
    method: 'POST',
    formData: {
      filename: buffer
    }
  }
}

router.post('/upload-image', function(req, res, next) {

  console.log('LOG 0' + Date.now());

  var data_url = req.body.file;
  var matches = data_url.match(/^data:.+\/(.+);base64,(.*)$/);
  var ext = matches[1];
  var base64_data = matches[2];
  var buffer = new Buffer(base64_data, 'base64');

  console.log('LOG 1' + Date.now());

  request(getOptions(buffer), function(error, response, body) {
    res.json(body);
    console.log(Date.now());
  });
});

我遇到的问题是LOG 0和LOG 1之间的线很慢,几秒钟。但图像只有650kb。有没有办法加速这个?

使用另一种方法读取标题,避免缓冲区,更改上传过程。我不知道,但我想要更快。

非常感谢。

1 个答案:

答案 0 :(得分:1)

我建议使用库来处理一些逻辑。如果您希望保留精益依赖列表,可以查看其中某些模块的来源,并根据它们建立自己的解决方案。

我特别推荐文件类型解决方案。更安全(不能说最安全)的方法来确保缓冲区是什么类型的文件是检查文件的各个方面。 文件类型似乎至少要查看要检查类型的文件的Magic Number。不是万无一失,但如果您接受用户的文件,您必须接受所涉及的风险。

另请参阅Security Stack Exchange有关良好做法的问题。虽然以下说PHP,但所有服务器软件都存在易受用户输入攻击的风险:

"use strict";

const dataUriToBuffer = require('data-uri-to-buffer'),
    fileType = require("file-type"),
    express = require("express"),
    router = express.Router(),
    util = require("util"),
    fs = require("fs"),
    path = require("path");

const writeFileAsync = util.promisify(fs.writeFile);

// Keep track of file types you support
const supportedTypes = [
    "png",
    "jpg",
    "gif"
];

// Handle POSTs to upload-image
router.post("/upload-image", function (req, res, next) {
    // Did they send us a file?
    if (!req.body.file) {
        // Unprocessable entity error
        return res.sendStatus(422);
    }

    // Get the file to a buffer
    const buff = dataUriToBuffer(req.body.file);

    // Get the file type
    const bufferMime = fileType(buff); // {ext: 'png', mime: 'image/png'}

    // Is it a supported file type?
    if (!supportedTypes.contains(bufferMime.ext)) {
        // Unsupported media type
        return res.sendStatus(415);
    }

    // Save or do whatever with the file
    writeFileAsync(path.join("imageDir", `userimage.${bufferMime.ext}`), buff)
        // Tell the user that it's all done
        .then(() => res.sendStatus(200))
        // Log the error and tell the user the save failed
        .catch((err) => {
            console.error(err);
            res.sendStatus(500);
        });
});