J'utilise les nœuds v0.10.26 et Express v4.2.0 et je suis assez nouveau dans ce domaine. Je frappe ma tête contre mon bureau depuis environ trois heures pour essayer d'obtenir un formulaire de téléchargement de fichier compatible avec node. À ce stade, j'essaie simplement de faire en sorte que req.files ne retourne pas undefined. Ma vue ressemble à ceci
<!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>
Voici mes itinéraires
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;
Et voici mon 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;
J'ai vu quelque part qu'inclure methodOverride()
et bodyParser({keepExtensions:true,uploadDir:path})
était supposé aider, mais je ne peux même pas lancer mon serveur si j'ajoute ces lignes.
Problème ExpressJS:
La plupart des middlewares sont supprimés de l'express 4. Consultez: http://www.github.com/senchalabs/connect#middleware Pour les middlewares en plusieurs parties tels que busboy, busboy-connect, formidable, flux, séparé est nécessaire.
Cet exemple fonctionne avec le middleware connect-busboy . créer des dossiers/img et/public.
Utilisez la structure de dossiers:
\ server.js
\ img\"où le contenu est chargé"
\ 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>
Ce qui suit fonctionnera avec formidable 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);
});
Une autre option consiste à utiliser multer , qui utilise busboy sous le capot, mais est plus simple à configurer.
var multer = require('multer');
Utilisez multer et définissez la destination du téléchargement:
app.use(multer({dest:'./uploads/'}));
Créez un formulaire dans votre vue, enctype='multipart/form-data
est requis pour que multer fonctionne:
form(role="form", action="/", method="post", enctype="multipart/form-data")
div(class="form-group")
label Upload File
input(type="file", name="myfile", id="myfile")
Ensuite, dans votre POST, vous pouvez accéder aux données relatives au fichier:
app.post('/', function(req, res) {
console.dir(req.files);
});
Un tutoriel complet sur ceci peut être trouvé ici .
Voici une version simplifiée ( du Gist ) de réponse de Mick Cullen - en partie pour prouver que la mise en œuvre de cette méthode n'est pas nécessairement complexe; en partie pour donner une référence rapide à quiconque n'est pas intéressé par la lecture de pages et de pages de code.
Vous devez vous faire utiliser l'application [connect-busboy] :
var busboy = require("connect-busboy");
app.use(busboy());
Cela ne fera rien jusqu'à ce que vous le déclenchiez. Dans l'appel qui gère le téléchargement, procédez comme suit:
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
});
Décomposons ceci:
req.busboy
est défini (le middleware a été chargé correctement)"file"
sur req.busboy
req
vers req.busboy
Dans l'écouteur de fichier, il y a quelques éléments intéressants, mais ce qui compte vraiment, c'est le fileStream
: il s'agit d'un Readable , qui peut ensuite être écrit dans un fichier, comme vous le feriez habituellement.
Piège: Vous devez gérer ceci en lecture, sinon Express ne répondra jamais à la demande , voir l'API busboy ( fichier section).
Je trouve cela simple et efficace:
app.post('/upload', function(req, res) {
if (!req.files)
return res.status(400).send('No files were uploaded.');
// The name of the input field (i.e. "sampleFile") is used to retrieve the uploaded file
let sampleFile = req.files.sampleFile;
// Use the mv() method to place the file somewhere on your server
sampleFile.mv('/somewhere/on/your/server/filename.jpg', function(err) {
if (err)
return res.status(500).send(err);
res.send('File uploaded!');
});
Il me fallait un peu plus de détails que les autres réponses fournies (par exemple, comment puis-je écrire le fichier dans un emplacement que je décide au moment de l'exécution?). J'espère que cela aidera les autres:
obtenir connect-busboy:
npm install connect-busboy --save
Dans votre server.js, ajoutez ces lignes
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('./images/' + filename);
file.pipe(fstream);
fstream.on('close', function () {
res.send('upload succeeded!');
});
});
});
Cela semblerait omettre le traitement des erreurs, mais le modifiera si je le trouve.
Voici un moyen plus simple qui a fonctionné pour moi:
const express = require('express');
var app = express();
var fs = require('fs');
app.post('/upload', async function(req, res) {
var file = JSON.parse(JSON.stringify(req.files))
var file_name = file.file.name
//if you want just the buffer format you can use it
var buffer = new Buffer.from(file.file.data.data)
//uncomment await if you want to do stuff after the file is created
/*await*/
fs.writeFile(file_name, buffer, async(err) => {
console.log("Successfully Written to File.");
// do what you want with the file it is in (__dirname + "/" + file_name)
console.log("end : " + new Date())
console.log(result_stt + "")
fs.unlink(__dirname + "/" + file_name, () => {})
res.send(result_stt)
});
});
Multer est un middleware node.js pour la gestion de multipart/form-data, principalement utilisé pour le téléchargement de fichiers. Il est écrit sur busboy pour une efficacité maximale.
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('/')
});