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).
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 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);
}
...
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 have an app to deduce the size of a file uploaded by the user. I have the code as follows
The server.js code is as follows
var express = require('express');
var formidable = require('express-formidable');
var fs = require('fs');
var app = express();
var PORT = 8080;
app.use(express.static(__dirname+'/views'));
app.use(formidable.parse());
app.set('views', './views');
app.set('view engine', 'jade');
app.get('/', function(req, res){
res.render('index.jade');
});
When I try to log the variable stats below, I get an error saying
TypeError: path must be a string
app.post('/upload', function(req, res){
var stats = fs.statSync(req.body);
console.log(stats);
});
app.listen(PORT, function(){
console.log('Express listening on port: '+PORT);
});
The index.jade file is rendered below
html
head
link(rel='stylesheet', href='style.css', type='text/css')
title Upload file for shortening
body
h1 Welcome to file metadata service
div(id='upload-button')
form(action='/upload', enctype='multipart/form-data')
input(name='Upload', type='file', id='upload-butt')
div(id="submit-button")
form(action = '/submit')
button(type="submit", value='Submit', id='submit-butt') Submit
script(src="https://code.jquery.com/jquery-2.2.0.min.js")
script(src="upload.js")
The css styling is below
#submit-butt{
width:100px;
height:auto;
background-color:red;
cursor:pointer;
margin-left:150px;
}
#upload-butt{
width:200px;
height:auto;
cursor:pointer;
float:left;
}
h1{
font-family:Impact;
}
The jQuery code is given below
$('#upload-butt').on('click', function(){
$('#upload-butt').on('change', function(){
var file = $(this).get(0).files;
if(file.length > 0){
var formData = new FormData();
formData.append('Upload', file, file.name);
$.ajax({
url: '/upload',
type: 'POST',
data:formData,
processData:false,
contentType:false,
success: function(data){
console.log('upload successful: '+data);
}
})
}
});
});
How do I deal with the TypeError? How do I convert the path to a string? What I have is the parsed data obtained after running through formidable middleware.
Change the '/upload' in backend to this code. Don't use req parameters in that. No need of that.
app.post('/upload', function(req, res){
// create an incoming form object
var form = new formidable.IncomingForm();
// specify that we want to allow the user to upload multiple files in a single request
form.multiples = true;
// store all uploads in the /uploads directory
form.uploadDir = path.join(__dirname, '/uploads');
// every time a file has been uploaded successfully,
// rename it to it's orignal name
form.on('file', function(field, file) {
fs.rename(file.path, path.join(form.uploadDir, file.name));
});
// log any errors that occur
form.on('error', function(err) {
console.log('An error has occured: \n' + err);
});
// once all the files have been uploaded, send a response to the client
form.on('end', function() {
res.end('success');
});
// parse the incoming request containing the form data
form.parse(req);
});
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);
});