2014-08-28 23 views
2

我目前正在我的應用程序中創建一個文件上傳系統。我的後端是Sails.js(10.4),它作爲我單獨前端(Angular)的API。Sails.js檢查上傳文件到MongoDB與船長(有效的文件,圖像大小等)之前的東西

我選擇將上傳到我的MongoDB實例的文件存儲起來,並使用sails'build in file upload module Skipper。我正在使用適配器隊長網格(https://github.com/willhuang85/skipper-gridfs)將文件上傳到mongo。

現在,上傳文件本身並不是問題:我在我的客戶端上使用dropzone.js,它將上傳的文件發送到/ api/v1/files/upload。這些文件將被上傳。

要做到這一點我使用我的FileController下面的代碼:

module.exports = { 
    upload: function(req, res) { 
     req.file('uploadfile').upload({ 
      // ...any other options here... 
      adapter: require('skipper-gridfs'), 
      uri: 'mongodb://localhost:27017/db_name.files' 
     }, function(err, files) { 
      if (err) { 
       return res.serverError(err); 
      } 
      console.log('', files); 
      return res.json({ 
       message: files.length + ' file(s) uploaded successfully!', 
       files: files 
      }); 
     }); 
    } 
}; 

現在的問題:我想要做的東西與他們的文件要上載之前。特別是兩件事:

  1. 檢查是否允許該文件:內容類型標題是否匹配我想允許的文件類型? (JPEG,PNG,PDF等 - 只是基本文件)。
  2. 如果文件是圖像,請使用imagemagick(或類似的東西)將其調整爲幾個預定義的大小。
  3. 添加也將保存到數據庫中的特定於文件的信息:對上傳文件的用戶的引用,以及該文件所屬模型(即文章/註釋)的引用。

我不知道從哪裏開始或如何實現這種功能。所以任何幫助將不勝感激!

回答

1

您可以指定.upload()函數的回調函數。例如:

req.file('media').upload(function (error, files) { 
    var file; 

    // Make sure upload succeeded. 
    if (error) { 
    return res.serverError('upload_failed', error); 
    } 

    // files is an array of files with the properties you want, like files[0].size 
} 

您可以撥打轉接器,與該文件從那裏上傳的.upload()的回調中。

+0

因此,如果我正確理解這一點,我應該首先使用默認的.upload函數,它將上傳的文件存儲在.tmp/uploads目錄中,並在第一個上傳函數的回調中執行我的自定義東西(如檢查文件類型等),然後使用skipper-gridfs發送給Mongo?我仍然可以在第一個回調中的文件上調用.upload? – Darkstra 2014-08-28 11:21:26

+0

我這麼認爲,是的。我沒有在任何地方看到「validate()」回調。 – 2014-08-28 11:27:59

+0

也許我在做一些愚蠢的事情,但是當我在回調中嘗試以下內容時: files [0] .upload({'adapter:require('skipper-gridfs'),uri:'mongodb:// localhost: 27017/evolution_api_v1.files'},函數(err,files){...}); 控制檯將死掉吐出'對象沒有方法上傳'。有點像我的預期。此外,我覺得有必要兩次上傳文件,這很奇怪。在文件上傳之前攔截文件會更好。不知道是否可以通過:)。 – Darkstra 2014-08-28 12:20:52

7

好的,擺弄這一段時間後,我設法找到了一種似乎有效的方法。

它可能會更好,但它做什麼,我想它現在做的事:

upload: function(req, res) { 
    var upload = req.file('file')._files[0].stream, 
     headers = upload.headers, 
     byteCount = upload.byteCount, 
     validated = true, 
     errorMessages = [], 
     fileParams = {}, 
     settings = { 
      allowedTypes: ['image/jpeg', 'image/png'], 
      maxBytes: 100 * 1024 * 1024 
     }; 

    // Check file type 
    if (_.indexOf(settings.allowedTypes, headers['content-type']) === -1) { 
     validated = false; 
     errorMessages.push('Wrong filetype (' + headers['content-type'] + ').'); 
    } 
    // Check file size 
    if (byteCount > settings.maxBytes) { 
     validated = false; 
     errorMessages.push('Filesize exceeded: ' + byteCount + '/' + settings.maxBytes + '.'); 
    } 

    // Upload the file. 
    if (validated) { 
     sails.log.verbose(__filename + ':' + __line + ' [File validated: starting upload.]'); 

     // First upload the file 
     req.file('file').upload({}, function(err, files) { 
      if (err) { 
       return res.serverError(err); 
      } 

      fileParams = { 
       fileName: files[0].fd.split('/').pop().split('.').shift(), 
       extension: files[0].fd.split('.').pop(), 
       originalName: upload.filename, 
       contentType: files[0].type, 
       fileSize: files[0].size, 
       uploadedBy: req.userID 
      }; 

      // Create a File model. 
      File.create(fileParams, function(err, newFile) { 
       if (err) { 
        return res.serverError(err); 
       } 
       return res.json(200, { 
        message: files.length + ' file(s) uploaded successfully!', 
        file: newFile 
       }); 
      }); 
     }); 
    } else { 
     sails.log.verbose(__filename + ':' + __line + ' [File not uploaded: ', errorMessages.join(' - ') + ']'); 

     return res.json(400, { 
      message: 'File not uploaded: ' + errorMessages.join(' - ') 
     }); 
    } 

}, 

而不是使用的隊長,GridFS的我選擇使用本地文件存儲的,但這個想法停留在相同。再次,它不像它應該是完整的,但它是一個簡單的方法來驗證簡單的東西,如文件類型和大小。如果有人有更好的解決方案,請張貼:)!

相關問題