Загрузка изображений с помощью Node.js, Express и Mongoose
Пожалуйста, рассмотрите более новые ответы, которые содержат более актуальную информацию, поскольку с годами они менялись!
Так как многие новые библиотеки Node.js быстро становятся устаревшими, и есть относительно мало примеров, я хочу спросить о загрузке изображений с использованием последних версий Node.js(v0.4.1), Express (1.0.7), и Mongoose (1.1.0). Как другие это сделали?
Я нашел: https://github.com/felixge/node-formidable, но я новичок в загрузке изображений в целом, поэтому я хочу узнать общие вещи и способы используя Node.js и Express.
Ответы
Ответ 1
Я отвечу на свой вопрос в первый раз. Я нашел пример прямо из источника. Пожалуйста, простите бедный отступ. Я не был уверен, как правильно отступать при копировании и вставке. Код приходит прямо из Express multipart/form-data
example в GitHub.
// Expose modules in ./support for demo purposes
require.paths.unshift(__dirname + '/../../support');
/**
* Module dependencies.
*/
var express = require('../../lib/express')
, form = require('connect-form');
var app = express.createServer(
// connect-form (http://github.com/visionmedia/connect-form)
// middleware uses the formidable middleware to parse urlencoded
// and multipart form data
form({ keepExtensions: true })
);
app.get('/', function(req, res){
res.send('<form method="post" enctype="multipart/form-data">'
+ '<p>Image: <input type="file" name="image" /></p>'
+ '<p><input type="submit" value="Upload" /></p>'
+ '</form>');
});
app.post('/', function(req, res, next){
// connect-form adds the req.form object
// we can (optionally) define onComplete, passing
// the exception (if any) fields parsed, and files parsed
req.form.complete(function(err, fields, files){
if (err) {
next(err);
} else {
console.log('\nuploaded %s to %s'
, files.image.filename
, files.image.path);
res.redirect('back');
}
});
// We can add listeners for several form
// events such as "progress"
req.form.on('progress', function(bytesReceived, bytesExpected){
var percent = (bytesReceived / bytesExpected * 100) | 0;
process.stdout.write('Uploading: %' + percent + '\r');
});
});
app.listen(3000);
console.log('Express app started on port 3000');
Ответ 2
Поскольку вы используете экспресс, просто добавьте bodyParser:
app.use(express.bodyParser());
то ваш маршрут автоматически получит доступ к загруженному файлу (-ам) в файлах req.files:
app.post('/todo/create', function (req, res) {
// TODO: move and rename the file using req.files.path & .name)
res.send(console.dir(req.files)); // DEBUG: display available fields
});
Если вы назовете входное управление "todo" следующим образом (в Jade):
form(action="/todo/create", method="POST", enctype="multipart/form-data")
input(type='file', name='todo')
button(type='submit') New
Затем загруженный файл готов к тому моменту, когда вы получите путь и исходное имя файла в файле files.todo:
- req.files.todo.path и
- req.files.todo.name
другие полезные свойства req.files:
- размер (в байтах)
- (например, 'image/png')
- lastModifiedate
- _writeStream.encoding(например, 'binary')
Ответ 3
Вы можете настроить промежуточное ПО парсера соединения тела в блоке конфигурации в главном файле приложения:
/** Form Handling */
app.use(express.bodyParser({
uploadDir: '/tmp/uploads',
keepExtensions: true
}))
app.use(express.limit('5mb'));
Ответ 4
Смотрите, самое лучшее, что вы можете сделать, это просто загрузить изображение на диск и сохранить URL-адрес в MongoDB. Отдых при повторном извлечении изображения. Просто укажите URL-адрес, и вы получите изображение. Код для загрузки выглядит следующим образом.
app.post('/upload', function(req, res) {
// Get the temporary location of the file
var tmp_path = req.files.thumbnail.path;
// Set where the file should actually exists - in this case it is in the "images" directory.
target_path = '/tmp/' + req.files.thumbnail.name;
// Move the file from the temporary location to the intended location
fs.rename(tmp_path, target_path, function(err) {
if (err)
throw err;
// Delete the temporary file, so that the explicitly set temporary upload dir does not get filled with unwanted files.
fs.unlink(tmp_path, function() {
if (err)
throw err;
//
});
});
});
Теперь сохраните целевой путь в базе данных MongoDB.
Опять же, извлекая изображение, просто извлеките URL из базы данных MongoDB и используйте его для этого метода.
fs.readFile(target_path, "binary", function(error, file) {
if(error) {
res.writeHead(500, {"Content-Type": "text/plain"});
res.write(error + "\n");
res.end();
}
else {
res.writeHead(200, {"Content-Type": "image/png"});
res.write(file, "binary");
}
});
Ответ 5
Попробуйте этот код. Это поможет.
app.get('/photos/new', function(req, res){
res.send('<form method="post" enctype="multipart/form-data">'
+ '<p>Data: <input type="filename" name="filename" /></p>'
+ '<p>file: <input type="file" name="file" /></p>'
+ '<p><input type="submit" value="Upload" /></p>'
+ '</form>');
});
app.post('/photos/new', function(req, res) {
req.form.complete(function(err, fields, files) {
if(err) {
next(err);
} else {
ins = fs.createReadStream(files.photo.path);
ous = fs.createWriteStream(__dirname + '/directory were u want to store image/' + files.photo.filename);
util.pump(ins, ous, function(err) {
if(err) {
next(err);
} else {
res.redirect('/photos');
}
});
//console.log('\nUploaded %s to %s', files.photo.filename, files.photo.path);
//res.send('Uploaded ' + files.photo.filename + ' to ' + files.photo.path);
}
});
});
if (!module.parent) {
app.listen(8000);
console.log("Express server listening on port %d, log on to http://127.0.0.1:8000", app.address().port);
}
Ответ 6
Вы также можете использовать следующее, чтобы установить путь, в котором он сохраняет файл.
req.form.uploadDir = "<path>";
Ответ 7
I создал пример, который использует Express и Multer. Это очень просто и позволяет избежать всех предупреждений Connect
Это может помочь кому-то.
Ответ 8
Для Express 3.0, если вы хотите использовать грозные события, вы должны удалить многостраничное промежуточное программное обеспечение, чтобы вы могли создать его новый экземпляр.
Для этого:
app.use(express.bodyParser());
Может быть записано как:
app.use(express.json());
app.use(express.urlencoded());
app.use(express.multipart()); // Remove this line
И теперь создайте объект формы:
exports.upload = function(req, res) {
var form = new formidable.IncomingForm;
form.keepExtensions = true;
form.uploadDir = 'tmp/';
form.parse(req, function(err, fields, files){
if (err) return res.end('You found error');
// Do something with files.image etc
console.log(files.image);
});
form.on('progress', function(bytesReceived, bytesExpected) {
console.log(bytesReceived + ' ' + bytesExpected);
});
form.on('error', function(err) {
res.writeHead(400, {'content-type': 'text/plain'}); // 400: Bad Request
res.end('error:\n\n'+util.inspect(err));
});
res.end('Done');
return;
};
Я также разместил это в своем блоге, Получение грозного объекта формы в Express 3.0 при загрузке.
Ответ 9
Опять же, если вы не хотите использовать bodyParser, работает следующее:
var express = require('express');
var http = require('http');
var app = express();
app.use(express.static('./public'));
app.configure(function(){
app.use(express.methodOverride());
app.use(express.multipart({
uploadDir: './uploads',
keepExtensions: true
}));
});
app.use(app.router);
app.get('/upload', function(req, res){
// Render page with upload form
res.render('upload');
});
app.post('/upload', function(req, res){
// Returns json of uploaded file
res.json(req.files);
});
http.createServer(app).listen(3000, function() {
console.log('App started');
});
Ответ 10
Я знаю, что исходный вопрос, связанный с конкретными версиями, но он также ссылался на пост "последний" - @JohnAllen, больше не уместен из-за Expressjs bodyParser и connect-form
Это демонстрирует простой в использовании встроенный bodyParser():
/**
* Module dependencies.
*/
var express = require('express')
var app = express()
app.use(express.bodyParser({ keepExtensions: true, uploadDir: '/home/svn/rest-api/uploaded' }))
app.get('/', function(req, res){
res.send('<form method="post" enctype="multipart/form-data">'
+ '<p>Image: <input type="file" name="image" /></p>'
+ '<p><input type="submit" value="Upload" /></p>'
+ '</form>');
});
app.post('/', function(req, res, next){
res.send('Uploaded: ' + req.files.image.name)
return next()
});
app.listen(3000);
console.log('Express app started on port 3000');
Ответ 11
Здесь вы можете загрузить свои изображения с помощью грозного пакета, который рекомендуется для bodyParser в более поздних версиях Express. Это также включает возможность изменения размера изображений на лету:
Загрузка и изменение размера изображений (на лету) С помощью Node.js и Express.
Здесь суть:
var express = require("express"),
app = express(),
formidable = require('formidable'),
util = require('util')
fs = require('fs-extra'),
qt = require('quickthumb');
// Use quickthumb
app.use(qt.static(__dirname + '/'));
app.post('/upload', function (req, res){
var form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files) {
res.writeHead(200, {'content-type': 'text/plain'});
res.write('received upload:\n\n');
res.end(util.inspect({fields: fields, files: files}));
});
form.on('end', function(fields, files) {
/* Temporary location of our uploaded file */
var temp_path = this.openedFiles[0].path;
/* The file name of the uploaded file */
var file_name = this.openedFiles[0].name;
/* Location where we want to copy the uploaded file */
var new_location = 'uploads/';
fs.copy(temp_path, new_location + file_name, function(err) {
if (err) {
console.error(err);
} else {
console.log("success!")
}
});
});
});
// Show the upload form
app.get('/', function (req, res){
res.writeHead(200, {'Content-Type': 'text/html' });
/* Display the file upload form. */
form = '<form action="/upload" enctype="multipart/form-data" method="post">'+ '<input name="title" type="text" />
'+ '<input multiple="multiple" name="upload" type="file" />
'+ '<input type="submit" value="Upload" />'+ '</form>';
res.end(form);
});
app.listen(8080);
ПРИМЕЧАНИЕ. Для этого требуется Магия изображения для быстрого изменения размера большого пальца.
Ответ 12
Там мой метод для множественного загружаемого файла:
Nodejs:
router.post('/upload', function(req , res) {
var multiparty = require('multiparty');
var form = new multiparty.Form();
var fs = require('fs');
form.parse(req, function(err, fields, files) {
var imgArray = files.imatges;
for (var i = 0; i < imgArray.length; i++) {
var newPath = './public/uploads/'+fields.imgName+'/';
var singleImg = imgArray[i];
newPath+= singleImg.originalFilename;
readAndWriteFile(singleImg, newPath);
}
res.send("File uploaded to: " + newPath);
});
function readAndWriteFile(singleImg, newPath) {
fs.readFile(singleImg.path , function(err,data) {
fs.writeFile(newPath,data, function(err) {
if (err) console.log('ERRRRRR!! :'+err);
console.log('Fitxer: '+singleImg.originalFilename +' - '+ newPath);
})
})
}
})
Убедитесь, что ваша форма имеет enctype = "multipart/form-data"
Надеюсь, это даст вам руку;)