2015-08-13 5 views
0

У меня есть приложение для загрузки, написанное в NodeJS с использованием Multer, которое отлично работает. Вот код:NodeJS Multer: конфигурация не применяется

var express = require('express'), 
    bodyParser = require('body-parser'), 
    qs = require('querystring'), 
    multer = require('multer'), 
    logger = require('morgan'); 

var config = require('./config'), 
    oauth = require('./oauth'); 

function extractExtension(filename) { 
    return filename.split('.').pop(); 
} 

function getRandom(min, max) { 
    return Math.floor(Math.random() * max) + min; 
} 


var app = express(); 
//app.use(cors()); 

// Add headers 
app.use(function(req, res, next) { 

    // Website you wish to allow to connect 
    res.setHeader('Access-Control-Allow-Origin', 'http://localhost:8080'); 

    // Request methods you wish to allow 
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE'); 

    // Request headers you wish to allow 
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,Authorization,content-type'); 

    // Set to true if you need the website to include cookies in the requests sent 
    // to the API (e.g. in case you use sessions) 
    res.setHeader('Access-Control-Allow-Credentials', true); 

    // Pass to next layer of middleware 
    next(); 
}); 

// Multer 
var momentUpload = multer({ 
    dest: './uploads/', 
    limits: { 
     fileSize: 256 * 1024 * 1024 
    }, 
    rename: function(fieldname, filename) { 
     return Date.now() + '-' + getRandom(100000, 999999) + '.' + extractExtension(filename); 
    }, 
    onFileUploadStart: function(file) { 
     console.log(file.originalname + ' is starting ...') 
    }, 
    onFileUploadComplete: function(file) { 
     console.log(file.fieldname + ' uploaded to ' + file.path) 
    } 
}).single('file'); 

app.set('port', 4000); 
app.use(logger('dev')); 
app.use(bodyParser.json()); 
app.use(bodyParser.urlencoded({ 
    extended: true 
})); 

app.post('/file/upload', [oauth.ensureAuthenticated, momentUpload, function(req, res) { 
    console.log(req.body); // form fields 
    console.log(req.file); // form files 

    res.status(204).end(); 
}]); 

// Start the Server 
app.listen(app.get('port'), function() { 
    console.log('Metadata store env: ' + config.METADATASTORE_ENV); 

    console.log('Express server listening on port ' + app.get('port')); 

    firebase.authenticate(); 
    console.log('Connected to Firebase'); 
}); 

Проблема, однако, что конфигурация Multer, кажется, не работает вообще. Работает destPath, и файлы появляются в папке, которую я предоставил (./uploads/). Допускаются большие размеры файлов (например, файл размером 400 МБ, в то время как в вариантах четко указано 256 МБ), а функции обратного вызова не запускаются один раз. Сообщение об ошибке отсутствует. Любая идея, что я делаю неправильно здесь? Я следил за гидами в Google и на официальной странице, но не могу заставить его работать.

ответ

1

Прежде всего, multer недавно изменил свой API, поэтому он больше не принимает rename, onFileUploadStart или onFileUploadComplete!

Мы можем взглянуть на API здесь https://github.com/expressjs/multer, поэтому давайте проанализируем, как все работает!

ПРИМЕЧАНИЕ. Если вы не обновили свою версию multer, я настоятельно рекомендую вам, потому что более старые версии, как предполагается, имеют нарушение безопасности.

Основы использования

Multer принимает то объект вариантов, самый основной из которых является собственностью Dest , который говорит Multer, где для загрузки файлов. В случае, если вы опустите объект опций, файлы будут сохранены в памяти и никогда не будут , записанные на диск.

По умолчанию Multer переименует файлы, чтобы избежать именования конфликтов. Функция переименования может быть настроена в соответствии с вашими потребностями . Объект options также принимает fileFilter (функция для управления загрузкой файлов) и limits (объект, который задает параметры размера).

Итак, ваш код будет выглядеть следующим образом (в отношении только multer части и учитывая, что вы хотели бы использовать все варианты, которые вы не должны):

// Multer 
var momentUpload = multer({ 
    dest: './uploads/', 
    limits: { 
     fileSize: 256 * 1024 * 1024 
    }, 
    fileFilter: function(req, file, cb) { 

     // The function should call `cb` with a boolean 
     // to indicate if the file should be accepted 

     // To reject this file pass `false`, like so: 
     cb(null, false) 

     // To accept the file pass `true`, like so: 
     cb(null, true) 

     // You can always pass an error if something goes wrong: 
     cb(new Error('I don\'t have a clue!')) 

    } 
}).single('file'); 

Если вы хотите, чтобы имеют больший контроль над хранением файлов, которые вы можете использовать движок хранения. Вы можете создать свой собственный или просто использовать доступные.

Доступные: diskStorage для хранения файлов на диске или memoryStorage для хранения файлов в памяти как Buffer объектов.

Поскольку вы явно хотите хранить файлы на диске, давайте поговорим о diskStorage.

Доступны два варианта: destination и filename.

destination используется для определения в какой папке загруженных файлы должны быть сохранены. Это также можно указать как строку (например, '/ tmp/uploads'). Если адресата не указана, используется каталог по умолчанию для временных файлов.

Примечание: вы несете ответственность за создание каталога при предоставлении адресата в качестве функции. При передаче строки multer сделает уверенным, что каталог создан для вас.

filename Используется для определения имени файла внутри папки. Если имя файла не указано, каждому файлу будет присвоено случайное имя, которое не включает расширение файла.

Итак, ваш код (относительно только multer часть) будет выглядеть следующим образом:

// Multer 
//Storage configuration 
var storageOpts = multer.diskStorage({ 
    destination: function (req, file, cb) { 
     //Choose a destination 
     var dest = './uploads/'; 

     //If you want to ensure that the directory exists and 
     //if it doesn't, it is created you can use the fs module 
     //If you use the following line don't forget to require the fs module!!! 
     fs.ensureDirSync(dest); 
     cb(null, dest); 
    }, 
    filename: function (req, file, cb) { 

     //here you can use what you want to specify the file name 
     //(fieldname, originalname, encoding, mimetype, size, destination, filename, etc) 
     cb(null, file.originalname); 
    } 
}); 

var momentUpload = multer({ 
    storage: storageOpts, 
    limits: { 
     fileSize: 256 * 1024 * 1024 
    }, 
    fileFilter: function(req, file, cb) { 

     // The function should call `cb` with a boolean 
     // to indicate if the file should be accepted 

     // To reject this file pass `false`, like so: 
     cb(null, false) 

     // To accept the file pass `true`, like so: 
     cb(null, true) 

     // You can always pass an error if something goes wrong: 
     cb(new Error('I don\'t have a clue!')) 

    } 
}).single('file'); 

Надеется, что это помогло! :)

Смежные вопросы