Я пытаюсь создать форму, которая загружает мои локальные файлы в мое ведро S3, но я немного не понимаю, где должны существовать части логики загрузки. Я хотел, чтобы мой маршрут POST был чистым и ссылался на логику AWS, которая размещена в отдельном файле, но я немного смущен тем, какое значение следует использовать для свойства Body для уровня параметров и как я должен ссылаться на этот модуль при установке URL завершенной загрузки в свойство моей базы данных в строке fileAttachment. Может кто-то указать мне верное направление?

Вот мой файл aws-s3.js:

module.exports = function() {

var path = require('path');
var async = require('async');
var fs = require('fs');
var AWS = require('aws-sdk');
var config = require(path.resolve(__dirname, '..', '..','./config/config.js'));

AWS.config.region = config.region;

var s3 = new AWS.S3({params: {Bucket: config.awsBucket}});

var params = {Key: config.awsAccessKeyId, Body: req.body.fileAttachment};

s3.upload(params, function(err, data){
    if (err) {
        console.log("Error uploading data: ", err);
    } else {
        console.log("Successfully uploaded data to " + config.awsBucket + " /myKey");

    }
});

return s3;

};

Вот мой маршрут:

appRoutes.route('/create/file')

    .get(function(req, res){
        models.DiscoverySource.findAll({
            where: {
                organizationId: req.user.organizationId
            }, attributes: ['discoverySource']
        }).then(function(discoverySource){
            res.render('pages/app/file-create.hbs',{
                discoverySource: discoverySource
            });
        });

    })



    .post(function(req, res){
        models.File.create({
            discovery: req.body.discovery,
            discoverySource: req.body.discoverySource,
            fileAttachment: 
            userId: req.user.user_id        
        }).then(function(){
            res.redirect('/app');
        });
    });

Форма:

<form action="/app/create/file" method="post">
                <div class="form-header">
                    <label for="data-discovery-source">Discovery Source:</label>
                    <select name="discoverySource">
                        {{#each discoverySource}}
                        <option value="{{this.discoverySource}}">{{this.discoverySource}}</option>
                        {{/each}}
                    </select>
                    <label for="data-discovery">Discovery:</label>
                    <textarea id="discovery-text-field" name="discovery"></textarea>
                    <label for="report-link">File Attachment:</label>
                    <input type="file" name="fileAttachment">
                </div>
                <button type="submit" id="create-button">Create File</button>
            </form>
2
cphill 30 Апр 2016 в 22:09

2 ответа

Лучший ответ

Можно попробовать использовать модуль multer-s3.

Он позволяет загружать файл с хранилищем, настроенным в AWS.

В этом коде используется модуль aws-sdk, и дополнительную информацию о его настройке можно найти здесь.

Вот мой пример кода:

Он использует рекомендуемый amazon AWS SDK для JavaScript в Node.js с И он также использует промежуточное ПО multer express для загрузки файлов.

var aws = require('aws-sdk')
var express = require('express')
var multer = require('multer')
var multerS3 = require('multer-s3')

var app = express()
var s3 = new aws.S3({ {accessKeyId: 'akid', secretAccessKey: 'secret'}) 
//this can also be configured in config file and through code



var upload = multer({
  storage: multerS3({
    s3: s3,
    bucket: 'some-bucket',
    key: function (req, file, cb) {
      cb(null, Date.now().toString())
    }
  })
})

//the upload.array -means that you can load multiple files(max 3) named photos maximum 3,  the resulting AWS full path urls will be returned in req.files 
app.post('/upload', upload.array('photos', 3), function(req, res, next) {
  //reference results that can be stored in database for example in req.files
  res.send('Successfully uploaded ' + req.files.length + ' files!')
})

В этом коде также используется модуль multer npm. Подробнее о возможностях конфигурации, таких как: single, any upload.array, fields, можно найти здесь.

3
Tal Avissar 2 Май 2016 в 03:43

Вы также можете использовать Minio-js, это пример presigned-postpolicy.js. Я надеюсь, что это помогает.

var Minio = require('minio')

var s3Client = new Minio({
  endPoint: 's3.amazonaws.com',
  accessKey: 'YOUR-ACCESSKEYID',
  secretKey: 'YOUR-SECRETACCESSKEY',
  insecure: false // Default is false.
})

// Construct a new postPolicy.
var policy = s3Client.newPostPolicy()
// Set the object name my-objectname.
policy.setKey("my-objectname")
// Set the bucket to my-bucketname.
policy.setBucket("my-bucketname")

var expires = new Date
expires.setSeconds(24 * 60 * 60 * 10) //10 days
policy.setExpires(expires)

policy.setContentLengthRange(1024, 1024*1024) // Min upload length is 1KB Max upload size is 1MB

s3Client.presignedPostPolicy(policy, function(e, formData) {
  if (e) return console.log(e)
  var curl = []
  curl.push('curl https://s3.amazonaws.com/my-bucketname')
  for (var key in formData) {
    if (formData.hasOwnProperty(key)) {
      var value = formData[key]
      curl.push(`-F ${key}=${value}`)
    }
  }
  // Print curl command to upload files.
  curl.push('-F file=@<FILE>')
  console.log(curl.join(' '))
}) 

Отказ от ответственности: я работаю с Minio, объектным хранилищем с открытым исходным кодом, совместимым с AWS S3.

2
koolhead17 1 Май 2016 в 07:21