I'm trying to save incoming file from FormData xhr request but i can't even parse incoming request. This is how i'm trying to send file:
...
let xhr = new XMLHttpRequest(),
formData = new FormData();
for(let i = 0; i < this.files.length; i++) {
formData.append(this.files[i], this.files[i].name);
}
xhr.open('POST', URL, true);
xhr.send(formData);
...
And this is how i'm trying to catch it:
var express = require('express');
var router = express.Router();
var multer = require('multer');
var uploads = multer({dest: './uploads/'});
router.post('/upload', uploads.any(), function (req, res) {
console.log(req.files); // []
console.log(req.file); // undefined
console.log(req.body); //{ '[object File]': '20160715_104330.jpg' }
});
The image comes on the server but is not writing to the directory uploads.
How I can save the image in the directory uploads?
I found the error. The following is the corrected code line:
formData.append( 'Choose your Fieldname', this.files[i], this.files[i].name);
I just needed to put the first parameter is a string representing the fieldname.
See the result in the backend:
var express = require('express');
var router = express.Router();
var multer = require('multer');
var uploads = multer({dest: './uploads/'});
router.post('/upload', uploads.any(), function (req, res) {
console.log(req.files);
/* [ { fieldname: 'Choose your Fieldname',
originalname: '20160715_104330.jpg',
encoding: '7bit',
mimetype: 'image/jpeg',
destination: './uploads/',
filename: '72b7a52101537ab1006f4feb0fa752be',
path: 'uploads\\72b7a52101537ab1006f4feb0fa752be',
size: 233509 } ]
*/
console.log(req.file); // undefined
console.log(req.body); //{}
});
Below is a smaller code in the frontend:
...
upload(){
let xhr = new XMLHttpRequest(),
formData = new FormData();
formData.append('Choose your Fieldname', this.files[0], this.files[0].name);
xhr.open('POST', URL, true);
xhr.send(formData);
}
...
Related
I am new to Node JS, so things are not coming easy to me. The scenario is I have input field which will accept multiple files.
<input id="upload-input" type="file" name="uploads[]" multiple="multiple">
in my JS script I grab the the change event of this field, and create a post request to my uploader app which is running in different port using formData and ajax post method
$('#upload-input').on('change', function() {
var files = $(this).get(0).files;
if (files.length > 0) {
var formData = new FormData();
formData.append('directory', "path/to/directory");
for (var i = 0; i < files.length; i++) {
var file = files[i];
formData.append('uploads[]', file, file.name);
}
$.ajax({
url: 'https://myurl.com:3000/upload',
type: 'POST',
data: formData,
processData: false,
contentType: false,
success: function(data) {
console.log(data);
},
});
}
});
Now the file is sending and in my backend I can upload that using formidable, but the problem is I cannot get the directory value, Here is my code
require('dotenv').load();
var express = require('express');
var app = express();
var path = require('path');
var formidable = require('formidable');
var fs = require('fs');
var session = require('express-session');
app.set('views', __dirname + '/public');
app.use('/uploads', express.static(process.env.USER_UPLOADS))
var cors=require('cors');
app.use(cors({origin:true,credentials: true}));
app.post('/upload', function(req, res) {
var user_folder = "path/to/directory/";
var form = new formidable.IncomingForm();
form.multiples = true;
form.uploadDir = path.join(__dirname, process.env.USER_UPLOADS + user_folder);
form.on('file', function(field, file) { fs.rename(file.path, path.join(form.uploadDir, file.name)); });
form.on('error', function(err) { console.log('An error has occured: \n' + err); });
form.on('end', function() { res.end('success'); });
form.parse(req);
});
var server = app.listen(3000, function(){
console.log('Server listening on port 3000');
});
I tried
console.log(req.body)
but it returns undefined, So how can I get the directory value from my backend?
Thanks in advance.
To fix your issue, I made some changes to your main app's server file
i.e. server.js/app.js/index.js anyone that applies to you. See changes below:
require('dotenv').load();
var express = require('express');
var app = express();
var path = require('path');
var bodyParser = require('body-parser');
var formidable = require('formidable');
var fs = require('fs');
var session = require('express-session');
var cors=require('cors');
app.set('views', __dirname + '/public');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cors({ origin:true, credentials: true }));
app.use('/uploads', express.static(process.env.USER_UPLOADS));
app.post('/upload', function(req, res) {
var user_folder = "path/to/directory/";
var form = new formidable.IncomingForm();
form.multiples = true;
form.uploadDir = path.join(__dirname, process.env.USER_UPLOADS + user_folder);
form.on('file', function(field, file) { fs.rename(file.path, path.join(form.uploadDir, file.name)); });
form.on('error', function(err) { console.log('An error has occured: \n' + err); });
form.on('end', function() { res.end('success'); });
// Note the changes here
form.parse(req, (error, fields, files) => {
console.log(JSON.stringify({
fields, // { directory: "path/to/directory" }
files // contains the uploaded files
}), null, 2);
});
});
var server = app.listen(3000, function(){
console.log('Server listening on port 3000');
});
According to the docs at here, form.parse can take an optional callback function.
Parses an incoming node.js request containing form data. If cb is provided, all fields and files are collected and passed to the callback:
form.parse(req, function(err, fields, files) {
// ...
});
I'm using angular file upload which previously did work when I used Laravel Lumen for the backend but I've moved to Node and unable to return the file contents of an upload.
FRONT END ANGULAR
$scope.upload = Upload.upload({
url: ENV.apiEndpoint + '/upload',
method: 'POST',
data: {
fname: $scope.fname
},
file: file
}).progress(function(evt) {
}).success(function(data, status, headers, config) {
});
BACK END NODE
upload/index.js
'use strict';
var express = require('express');
var controller = require('./upload.controller');
var router = express.Router();
var multer = require('multer');
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './my-uploads');
},
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now());
}
})
var upload = multer({ storage: storage });
router.post('/', upload.single('file'), controller.index);
module.exports = router;
upload/upload.controller.js
'use strict';
var _ = require('lodash');
var db = require('../../db');
var https = require('https');
var Q = require('q');
var fs = require('fs');
var multer = require('multer');
exports.index = function(req, res, next) {
console.log(req.files.file);
res.status(204).end();
};
Old Laravel Lumen Request
public function data(Request $request) {
$path_parts = pathinfo($_FILES["file"]["name"]);
$extension = $path_parts['extension'];
$contents = file_get_contents( $_FILES['file']['tmp_name'] );
return response()->json(['type'=> $extension, 'content'=> $contents]);
}
All I'm looking to do is upload a file but only return the contents of the file to the front end again I dont want the file to be stored.
Here you have an example, you have a couple of things wrong. Check it out
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'public/images/banks')
},
filename: function (req, file, cb) {
crypto.pseudoRandomBytes(16, function (err, raw) {
cb(null, raw.toString('hex') + path.extname(file.originalname));
});
}
});
var upload = multer({storage: storage});
router.post('/uploadImage', upload.single('file'), function (req, res, next) {
if(!req.file) {
res.status(400);
res.send({error: 'No se pudo subir el archivo'});
}
res.send({filename: req.file.filename});
});
Trying to send a blob object to my node server. On the client side I'm recording some audio using MediaRecorder and then I want to send the file to my server for processing.
saveButton.onclick = function(e, audio) {
var blobData = localStorage.getItem('recording');
console.log(blobData);
var fd = new FormData();
fd.append('upl', blobData, 'blobby.raw');
fetch('/api/test',
{
method: 'post',
body: fd
})
.then(function(response) {
console.log('done');
return response;
})
.catch(function(err){
console.log(err);
});
}
This is my express route, which uses multer:
var upload = multer({ dest: __dirname + '/../public/uploads/' });
var type = upload.single('upl');
app.post('/api/test', type, function (req, res) {
console.log(req.body);
console.log(req.file);
// do stuff with file
});
But my logs return nothing:
{ upl: '' }
undefined
Been spending a long time on this so any help appreciated!
I was just able to run a minimum configuration of your above example and it worked fine for me.
Server:
var express = require('express');
var multer = require('multer');
var app = express();
app.use(express.static('public')); // for serving the HTML file
var upload = multer({ dest: __dirname + '/public/uploads/' });
var type = upload.single('upl');
app.post('/api/test', type, function (req, res) {
console.log(req.body);
console.log(req.file);
// do stuff with file
});
app.listen(3000);
HTML file in public:
<script>
var myBlob = new Blob(["This is my blob content"], {type : "text/plain"});
console.log(myBlob);
// here unnecessary - just for testing if it can be read from local storage
localStorage.myfile = myBlob;
var fd = new FormData();
fd.append('upl', localStorage.myfile, 'blobby.txt');
fetch('/api/test',
{
method: 'post',
body: fd
});
</script>
The console.log(myBlob); on the frontend is printing Blob {size: 23, type: "text/plain"}. The backend is printing:
{}
{ fieldname: 'upl',
originalname: 'blobby.txt',
encoding: '7bit',
mimetype: 'text/plain',
destination: '/var/www/test/public/uploads/',
filename: 'dc56f94d7ae90853021ab7d2931ad636',
path: '/var/www/test/public/uploads/dc56f94d7ae90853021ab7d2931ad636',
size: 23 }
Maybe also try it with a hard-coded Blob like in this example for debugging purposes.
You don't need to use multer. Just use express.raw() inside app.post()
var express = require('express');
var app = express();
app.use(express.static('public')); // for serving the HTML file
app.post('/api/test', express.raw({type: "*/*"}), function (req, res) {
console.log(req.body);
// do stuff with file
});
app.listen(3000);
i'm trying to upload an image to my express-nodejs server with multer and req.file is undefined :
server.js :
var express = require('express');
var app = express();
var multer = require('multer');
...
var upload = multer({ dest: './img-user' });
app.post('/api/img-user/:title', upload.single('file'), function(req, res, next){
console.log(req.file); //form files
console.log(__dirname);
res.status(204).end();
});
register.js :
form.onsubmit = function () { return false };
if (xhr2.readyState == 4 && xhr2.status === 200 ){
console.log(xhr.responseText);
}
fd = new FormData();
fd.append('file', document.getElementById("upload-button").files[0]);
xhr2.open("POST", "http://myAPI/"+fields.username.value, true);
xhr2.setRequestHeader("Content-type", false);
xhr2.send(fd);
register.jade :
form(name='form', role='form', enctype='multipart/form-data')
.form-group
.fileUpload.btn.btn-primary#picture
span Picture
input.upload#upload-button(my-upload, file="file", type='file', name='file', accept='image/*')
I don't want to use the form html tag but the FormData js object and xmlhttprequest, NOT $.ajax (absolutly not jQuery).
I am trying to upload images to node.js express
bodyParser need a middleware to handle the image file , or it will reply
token undefine
I use Multer as middle ware , as this said, the req.file should hole a array of information, than I can use req.file.image.path to get the file path and other information, than I can save it as a file.
Here is the problem, I upload an image from Postman, I only write console.log(req.file) it shows undefined.
If I try to write req.file.image.path to get the file path, the error is image undefined, it seems like I didn't use multer well, so the req.file didn't hold the data information, Should I create some temp folder to multer or...?
app.js
var express = require('express')
,bodyParser = require('body-parser')
,app = express()
,multer = require('multer')
,binary = require('binary')
,fs = require('fs')
,util= require('util')
,http = require('http')
,multer = require('multer')
,upload = multer({ dest: '/Node/file-upload/uploads/' });
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies.
app.use(bodyParser.json({limit: '5mb'}));
songs = require('./routes/route');
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
app.post('/upload',songs.upload);
route.js
var mongoose = require('mongoose');
var uri = "mongodb://1111:1111#ds061365.mongolab.com:61365/aweitest";
mongoose.connect(uri);
// we're connected!
var db = mongoose.connection.db;
var BSON = require('bson').BSONPure;
var binary = require('binary');
var body = require('body-parser');
var fs = require('fs');
var multer = require('multer');
var storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, '/Node/file-upload/uploads/');
},
filename: function (req, file, callback) {
callback(null, file.fieldname + '-' + Date.now());
}
});
var upload = multer({ storage : storage}).single('image');
db.on('error', console.error.bind(console, 'connection errrrrrrrror:'));
db.once('open', function() {
console.log("mongodb is connected!!");
});
exports.upload = function(req, res) {
upload(req,res,function(err) {
console.log(req.file);
fs.readFile(req.file.image.path, function (err, data){
var dirname = "/Node/file-upload/uploads/";
var newPath = dirname + req.body.filename;
fs.writeFile(newPath, data, function (err) {
if(err) {
return res.end("Error uploading file.");
}
res.end("File is uploaded");
});
});
});
};
error
TypeError: Cannot read property 'image' of undefined
at c:\Users\awei\WebstormProjects\untitled\routes\girlshanlder.js:107:28
You need to set the filename before send the image in the Postman as shown here
Cheers.
Full code for uploading images in your MySQL database and in folder too.
Just define the module and install multer and path and save it.
var multer = require('multer');
var path = require('path');
var storage = multer.diskStorage({
destination: function(req, file, callback) {
callback(null, './uploadimages')
},
filename: function(req, file, callback) {
callback(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname))
}
})
app.post('/imginsert',multer({
storage: storage,
fileFilter: function(req, file, callback) {
var ext = path.extname(file.originalname)
if (ext !== '.png' && ext !== '.jpg' && ext !== '.gif' && ext !== '.jpeg')
{
return callback(res.end('Only images are allowed'), null)
}
callback(null, true)
}
}).single('img'), function(req, res) {
/*img is the name that you define in the html input type="file" name="img" */
var data = {
table_column_name(your database table column field name) :req.file
};
var query = connection.query("Insert into tablename set ?" ,data,function(err, rows)
{
if (err)
throw err;
res.redirect('/blog');
});
console.log(query.sql);
console.log(req.file);
});