Node.js通过REST API发送图像

时间:2017-01-07 17:59:59

标签: node.js mongodb rest gridfs file-storage

我正在努力寻找这个材料

我有一个用node.js编写的rest API,它使用mongoDB。

我希望用户能够上传图片(个人资料图片)并将其保存在服务器上(在mongoDB中)。

有几个问题,我看过建议使用GridFS,这是最好的解决方案吗?

如何发送这些文件?我见过res.sendFile,但这又是最好的解决方案吗?

如果有人有任何材料,他们可以链接我,我会很感激

感谢

4 个答案:

答案 0 :(得分:2)

您无法直接在服务器上获取文件对象。要在服务器上获取文件对象,请使用connect-multiparty中间件。这将允许您访问服务器上的文件。

var multipart = require('connect-multiparty');
var multipartmiddleware = multipart();
var mv = require('mv');
var path = require('path');

app.post("/URL",multipartmiddleware,function(req,res){
    var uploadedImage = req.files.file;
    for (var i = 0; i < uploadedImage.length; i++) {
        var tempPath = uploadedImage[i].path;
        var targetPath = path.join(__dirname ,"../../../img/Ads/" + i + uploadedImage[i].name);

        mv(tempPath, targetPath, function (err) {
           if (err) { throw err; }
        });
    }
})

答案 1 :(得分:1)

使用文件系统

  

通常在任何数据库中将图像位置存储在数据中作为字符串,告诉应用程序图像存储在文件系统中

     

除非您的数据库需要作为一个单元进行移植,否则将数据库内部的图像存储为二进制对象通常会给数据库增加不必要的大小和复杂性。
   - Michael Stearne

     

在MongoDB中,使用GridFS存储大于16 MB的文件。    - Mongo Documentation

因此,除非您的图像超过16 MB,否则您应该将文件存储在CDN(首选)或服务器自己的文件系统中,并将其URL保存到数据库上的用户文档中。

本地文件系统实现

此方法使用Busboy来解析照片上传。

  

在相关的html文件中:

      
<input type="file" title="Choose a file to upload" accept="image/*" autofocus="1">
     

服务器文件中照片上传路径的处理程序功能(您需要填写适用于您的变量并需要必要的模块):

      
function photoUploadHandlerFunction (req, res) {
  var busboy = new Busboy({ headers: req.headers })
  busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {
    const saveToDir = path.join(__dirname, uploadsPath, user.id)
    const saveToFile = path.join(saveToDir, filename)
    const pathToFile = path.join(uploadsPath, user.id, filename)
    const writeStream = fs.createWriteStream(saveToFile)

    createDirIfNotExist(saveToDir)
      .then(pipeUploadToDisk(file, writeStream))
      .then(findUserAndUpdateProfilePic(user, pathToFile))
      .catch((err) => {
        res.writeHead(500)
        res.end(`Server broke its promise ${err}`)
      })
  })

  busboy.on('finish', function () {
    res.writeHead(200, { 'Connection': 'close' })
    res.end("That's all folks!")
  })

  return req.pipe(busboy)
}
     

承诺函数createDirIfNotExistpipeUploadToDisk可能如下所示:

      
function createDirIfNotExist (directory, callback) {
  return new Promise(function (resolve, reject) {
    fs.stat(directory, function (err, stats) {
      // Check if error defined and the error code is "not exists"
      if (err) {
        if (err.code === 'ENOENT') {
          fs.mkdir(directory, (err) => {
            if (err) reject(err)
            resolve('made folder')
          })
        } else {
          // just in case there was a different error:
          reject(err)
        }
      } else {
        resolve('folder already existed')
      }
    })
  })
}

function pipeUploadToDisk (file, writeStream) {
  return new Promise((resolve, reject) => {
    const fileWriteStream = file.pipe(writeStream)
    fileWriteStream.on('finish', function () {
      resolve('file written to file system')
    })
    fileWriteStream.on('error', function () {
      reject('write to file system failed')
    })
  })
}

要回答您的问题'我如何发送这些文件?',我需要知道在哪里(MongoDB,客户端......)。如果您是对客户的意思,您可以提供保存它们的静态文件夹。

如果您仍想学习实施GridFs,那么教学点会有good tutorial

更多资料

答案 2 :(得分:0)

如果你正在使用mongoose odm,你可以使用Walkthrough creating a local database SQL Server Express模块并将文件发送到任何地方进行存储。

答案 3 :(得分:0)

此外,这是AWS S3或Azure blob存储等共享对象存储的一个很好的案例。如果您在AWS之类的设备上运行分布式设置,通常不希望在本地服务器上存储照片。

将url或key名称存储在指向S3对象的数据库中。这也很容易与CloudFront CDN集成。

如前所述。用于实际上传的MultiPart。