I am trying to upload a file in nodejs using express and multer.
index.js
var mysql=require('mysql');
var session = require('express-session');
var multer=require('multer');
var express=require('express');
var path=require('path');
var cors=require('cors');
var nodemailer=require('nodemailer');
var fileupload=require('express-fileupload');
var fs=require('fs');
const app=express();
app.use(cors());
app.use(fileupload());
var bodyParser=require('body-parser');
app.use(bodyParser.json({limit: '5mb'}));
app.use(bodyParser.urlencoded({limit: '5mb',extended:true}));
require('./routes.js')(app,mc,fs,multer);
app.listen(8080,function() {
console.log('port listening on 8080');
})
routes.js
module.exports=function(app,mc,fs,multer) {
var storages = multer.diskStorage({
destination: function(req, file, callback) {
callback(null, './uploads')
},
filename: function(req, file, callback) {
console.log(file)
callback(null, file.fieldname + '-' + Date.now() +
path.extname(file.originalname))
}
})
app.post('/reactTest',function(req,res) {
var uploads = multer({
storage: storages,
fileFilter: function(req, file, callback) {
var ext = path.extname(file.originalname);
if (ext !== '.png' && ext !== '.jpg' && ext !== '.gif' && ext !== '.jpeg') {
res.send('Only images are allowed');
}
else {
fs.exists('./uploads/'+file.originalname, function(exists) {
console.log(exists);
if(exists) {
res.send('images already uploaded');
}
else {
callback(null, true);
}
})
}
}
}).single('user.uploadContent');
uploads(req, res, function(err) {
console.log(req.body);
res.send('File is uploaded');
})
})
app.get('/',function(req,res) {
var localTutor=require('./child.js');
localTutor.NodeTutorial()();
res.writeHead(200,{'Content-Type':'text/html'});
res.write('<form action="fileUpload" method="post" enctype="multipart/form-data">');
res.write('<input type="file" name="files" >');
res.write('<br><input type="submit" >');
res.write('</form>');
res.send();
//return res.send({error:true,message:'working'});
//res.render('html');
})
app.post('/fileUpload',function(req,res) {
var uploads = multer({
storage: storages
}).single('files');
uploads(req, res, function(err) {
if(err) {
throw err;
}
return res.send({status:'file uploaded'});
})
})
}
front-end
handleSubmit=(values,event)=> {
console.log(values);
const forms=new FormData(event.target);
let promise=fetch('http://localhost:8080/reactTest', {
method:'POST',
mode:'CORS',
body:forms,
headers:{
}
}).then(res =>res.json()).then(result=>console.log(result))
}
when i uploaded a file it returns status as "file uploaded", but the file is doesn't uploaded to the directory.I don't know what the issue here is?
I am also attaching the code to create a restful api at front-end side.
as #wdetac said , remove app.use(fileupload()); then add var path=require('path'); to your routes.js file
a working example
views/index.ejs
<form action="fileUpload" method="post" enctype="multipart/form-data"
id="form-id">
<input type="file" id="file-select" name="files" multiple/><br/>
<input type="text" name="email" id="email"><br>
<button type="submit" id="upload-button">Upload</button>
</form>
<script>
var form = document.getElementById('form-id');
var fileSelect = document.getElementById('file-select');
var uploadButton = document.getElementById('upload-button');
form.onsubmit = function(event) {
event.preventDefault();
var files = fileSelect.files;
var formData = new FormData();
for (var i = 0; i < files.length; i++) {
var file = files[i];
if (!file.type.match('image.*')) {
continue;
}
formData.append('files', file, file.name);
}
var email = document.getElementById('email').value;
formData.append('email',email);
let promise=fetch('http://localhost:8080/reactTest', {
method:'POST',
mode:'CORS',
body:formData
}).then(res =>res.json()).then(result=>console.log(result))
}
</script>
routes.js
app.post('/reactTest',function(req,res) {
var uploads = multer({
storage: storages,
fileFilter: function(req, file, callback) {
var ext = path.extname(file.originalname);
if (ext !== '.png' && ext !== '.jpg' && ext !== '.gif' && ext !== '.jpeg') {
res.send('Only images are allowed');
}
else {
fs.exists('uploads/'+file.originalname, function(exists) {
console.log(exists);
if(exists) {
res.send('images already uploaded');
}
else {
callback(null, true);
}
})
}
}
}).single('files');
uploads(req, res, function(err) {
console.log('----------',req.body);
res.send('File is uploaded');
})
})
Related
I am uploading a video file to a local folder using form, multer, express and nodejs.
The video file gets uploaded to the local folder - everytime I upload it through the form. However, the code inside upload executes only occasionally. Once in 5 times. i.e. console.log('33'); inside the app.post doesn't always get printed. However, console.log('1') (the one inside post and before upload) works everytime.
server.js code
var Express = require('express');
var multer = require('multer');
var mkdirp = require('mkdirp');
var app = Express();
var cors = require('cors');
app.use(cors());
var Storage = multer.diskStorage({
destination: function(req, file, cb) {
var dir = './client/public/video/';
mkdirp(dir, function(err) {
if(err) {
console.error(err);
}
cb(null, dir);
});
console.log("Upload: saved to " + dir + file.originalname);
},
filename: function(req, file, callback) {
callback(null, file.fieldname + "_" + Date.now() + "_" + file.originalname);
}
});
var upload = multer({
storage: Storage
}).single("file");
app.post("/api", function(req, res) {
console.log('1');
upload(req, res, function(err) {
console.log('33');
if (err) {
return res.end("Something went wrong!");
}
return res.status(200).end("File uploaded successfully!.");
});
});
var server = app.listen(9000, function () {
console.log('app listening at 9000');
});
app.js code
import React, { Component } from "react";
import axios from "axios";
class App extends Component {
state = {
file: null
};
handleOnChange = e => this.setState({ [e.target.name]: e.target.value });
handleOnUploadFile = e => this.setState({ file: e.target.files[0] });
handleOnSubmit = e => {
e.preventDefault();
const formData = new FormData();
formData.append("file", this.state.file);
axios
.post("http://localhost:9000/api", formData, {
headers: {
'accept': 'video/mp4',
'Accept-Language': `en-US,en;q=0.8`,
'Content-Type': `multipart/form-data; boundary=${formData._boundary}`,
}
})
.then(res => console.log(res.data))
.catch(err => console.error(err));
};
render() {
return (
<form>
<input type="file" encType="multipart/form-data"
name="file"
accept="video/mp4"
onChange={this.handleOnUploadFile}/>
<button type="submit" className="btn btn-danger" onClick={this.handleOnSubmit}>
Submit
</button>
</form>
);
}
}
export default App;
I am new to react/node js. Tried a lot of suggestions from other posts, but couldn't find the solution.
Try adding async and await.
server.js
var Express = require('express');
var multer = require('multer');
var mkdirp = require('mkdirp');
var app = Express();
var cors = require('cors');
app.use(cors());
var Storage = multer.diskStorage({
destination: function(req, file, cb) {
var dir = './client/public/video/';
mkdirp(dir, function(err) {
if(err) {
console.error(err);
}
cb(null, dir);
});
console.log("Upload: saved to " + dir + file.originalname);
},
filename: function(req, file, callback) {
callback(null, file.fieldname + "_" + Date.now() + "_" + file.originalname);
}
});
var upload = multer({
storage: Storage
}).single("file");
app.post("/api", function(req, res) {
console.log('1');
upload(req, res, function(err) {
console.log('33');
if (err) {
return res.end("Something went wrong!");
}
return res.status(200).end("File uploaded successfully!.");
});
});
app.get("/", function(req, res) {
console.log('1');
return res.status(200).json({});
});
var server = app.listen(9900, function () {
console.log('app listening at 9900');
});
App.js
import React, { Component } from "react";
import axios from "axios";
class App extends Component {
state = {
file: null
};
handleOnChange = e => this.setState({ [e.target.name]: e.target.value });
handleOnUploadFile = e => this.setState({ file: e.target.files[0] });
handleOnSubmit = async e => {
e.preventDefault();
const formData = new FormData();
formData.append("file", this.state.file);
await axios
.post("http://localhost:9900/api", formData, {
headers: {
'accept': 'video/mp4',
'Accept-Language': `en-US,en;q=0.8`,
'Content-Type': `multipart/form-data; boundary=${formData._boundary}`,
}
})
.then(res => console.log(res.data))
.catch(err => console.error(err));
};
render() {
return (
<>
<h1>{"<b>hello</b>".bold()}</h1>
<form>
<input type="file" encType="multipart/form-data"
name="file"
accept="video/mp4"
onChange={this.handleOnUploadFile}/>
<button type="submit" className="btn btn-danger" onClick={this.handleOnSubmit}>
Submit
</button>
</form>
</>
);
}
}
export default App;
Try using a promise for your upload function:
var Express = require('express');
var multer = require('multer');
var mkdirp = require('mkdirp');
var app = Express();
var cors = require('cors');
app.use(cors());
var Storage = multer.diskStorage({
destination: function(req, file, cb) {
var dir = './client/public/video/';
mkdirp(dir, function(err) {
if(err) {
console.error(err);
}
cb(null, dir);
});
console.log("Upload: saved to " + dir + file.originalname);
},
filename: function(req, file, callback) {
callback(null, file.fieldname + "_" + Date.now() + "_" + file.originalname);
}
});
var upload = multer({
storage: Storage
}).single("file");
app.post("/api", function(req, res) {
console.log('1');
upload(req, res).then((file, err) => {
console.log('33');
if (err) {
return res.end("Something went wrong!");
}
return res.status(200).end("File uploaded successfully!.");
})
});
var server = app.listen(9000, function () {
console.log('app listening at 9000');
});
Another idea would be to wrap the upload itself in a promise:
var Storage = multer.diskStorage({
return new Promise((resolve, reject) => {
destination: function(req, file, cb) {
var dir = './client/public/video/';
mkdirp(dir, function(err) {
if(err) {
reject(err)
}
cb(null, dir);
});
console.log("Upload: saved to " + dir + file.originalname);
},
filename: function(req, file, callback) {
resolve(callback(null, file.fieldname + "_" + Date.now() + "_" + file.originalname);)
}
})
});
I am having an issue in uploading the file to pc as well as DB at same time.
I am using two different Modules in my code
Multer: For uploading file from front-end to PC
CSV-to-JSON: For converting CSV File to json in order to store that file in Database.
But, using two separate functions isn't my intention at all.
So, when I tried combining both modules along with the base code, File uploading with Multer works but I want to upload that file to MongoDB which need to be solved by csv-to-json is a problem for me nothing seem's to be working.
here's is my code :
var express = require('express');
var multer = require('multer');
const csv = require('csvtojson');
// Import Mongodb
const mongoClient = require('mongodb').MongoClient,
assert = require('assert');
var filename = null;
var storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, 'uploads/')
},
filename: function(req, file, cb) {
filename = Date.now() + '-' + file.originalname;
cb(null, filename)
console.log(filename);
}
})
var upload = multer({
storage: storage
})
var app = express();
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
app.post('/', upload.single('file-to-upload'), function(req, res, next) {
// Mongodb Connection URL
const url = 'mongodb://localhost:27017/csvfilereader';
// Use connect method to connect to the Server
mongoClient.connect(url, (err, db) => {
assert.equal(null, err);
if (db) {
console.log("Connected correctly to server");
insertDocuments(db, function() {
db.close();
});
} else {
console.log('\n', 'Problem with connection', err)
}
});
const insertDocuments = (db, callback) => {
// Get the documents collection
let collection = db.collection('uploaded');
// CSV File Path
const csvFilePath = 'uploads/' + filename;
console.log(csvFilePath);
/**
* Read csv file and save every row of
* data on mongodb database
*/
csv()
.fromFile(csvFilePath)
.on('json', (jsonObj) => {
collection.insert(jsonObj, (err, result) => {
if (err) {
console.log(err);
} else {
console.log('suceess');
res.redirect('/');
filename = null;
}
});
})
.on('done', (error) => {
console.log('end')
})
}
});
app.listen(3200);
<!--
HTML Code that runs on Root
-->
<html lang="en">
<head>
<title>Simple Multer Upload Example</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<form action="/" enctype="multipart/form-data" method="post">
<input type="file" name="file-to-upload">
<input type="submit" value="Upload">
</form>
</body>
</html>
You need to access the file name through the passed request from multer. Your filename variable doesn't point to any object.
req.file.filename will give access to your file that has been uploaded by multer.
UPDATED CODE:
var express = require("express");
var multer = require("multer");
const csv = require("csvtojson");
// Import Mongodb
const MongoClient = require("mongodb").MongoClient,
assert = require("assert");
var filename = null;
var storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, "uploads/");
},
filename: function(req, file, cb) {
filename = Date.now() + "-" + file.originalname;
cb(null, filename);
},
});
var upload = multer({
storage: storage,
});
var app = express();
app.get("/", (req, res) => {
res.sendFile(__dirname + "/index.html");
});
app.post("/", upload.single("file-to-upload"), function(req, res, next) {
// Connection URL
const url = "mongodb://localhost:27017";
console.log("Multer", req.file.filename);
// Database Name
const dbName = "csvreader";
// Create a new MongoClient
const client = new MongoClient(url, { useNewUrlParser: true });
// Use connect method to connect to the Server
client.connect(function(err) {
assert.equal(null, err);
console.log("Connected successfully to database");
const db = client.db(dbName);
insertDocuments(db, function() {
console.log("Closing connection");
client.close();
});
});
const insertDocuments = (db, callback) => {
// Get the documents collection
const collection = db.collection("uploaded");
// CSV File Path
const csvFilePath = "uploads/" + filename;
console.log("Reading file from ", csvFilePath);
/**
* Read csv file and save every row of
* data on mongodb database
*/
csv()
.fromFile(csvFilePath)
.then(jsonObj => {
console.log(jsonObj);
collection.insert(jsonObj, (err, result) => {
if (err) {
console.log(err);
} else {
console.log("suceess");
res.redirect("/");
filename = null;
callback();
}
});
})
.catch(err => {
//error reading file
console.log(err);
});
};
});
app.listen(3200, () => {
console.log("Server working at port 3200");
});
I'm having some problems when trying to stream videos in nodejs. When I tried just pass the video path to the source/video html tag, it doenst worked. Then, I realized that problably I would have to stream the video.
The problem is: When I stream the video, I just get the video being played in the browser, as a direct link to some downloaded video, not the renderized page with some data(video title and path).
I wanna render the page and then run the video.
When I render, I receive the error: "Can't set headers after they're sent".
My code:
const express = require('express')
const multer = require('multer')
const moment = require('moment')
const uuidv4 = require('uuid/v4');
const bodyParser = require('body-parser')
const fs = require('fs')
const videoLib = require('node-video-lib')
const app = express()
const db = require('./db')
let Video = require('./models/videoModel')
//***** STAND LIBRARIES CONFIGURATION **********//
app.use(bodyParser.urlencoded({extended:true}))
app.use(bodyParser.json())
app.set('views', 'views')
app.set('view engine', 'ejs')
app.set(db)
//***** MULTER CONFIGURATION ***************//
let storage = multer.diskStorage({
destination: function(req, file, cb){
cb(null, './uploads')
},
filename: function(req, file, cb){
let mime = file.mimetype.split('/')[1]
let uuid = uuidv4()
cb(null, uuid + "." + mime)
}
})
function fileFilter(req, file, cb){
const extension = file.mimetype.split('/')[0];
if(extension !== 'video'){
return cb(new Error('Something went wrong. Wrong file format'), false);
}
cb(null, true);
};
var upload = multer({storage:storage, fileFilter: fileFilter})
const uploadHandler = upload.single('video')
function uploadVideo(req, res, next){
uploadHandler(req, res, next, function(err){
if(req.fileValidationError){
res.send('Error when upload')
}
console.log(req.file.filename)
next()
})
}
//******************************************//
function newVideo(req, res){
let videoParams = {title: req.body.title, path: req.file.filename}
Video.create(videoParams, function(err, result){
if(err){
console.log(err)
}
else{
console.log("Video salvo com sucesso")
console.log(result)
res.send(result )
}
})
}
app.get('/videos/:id', function(req, res){
let path = req.params.id
Video.find({path:path}, function(err, result){
if(err){
console.log(err);
}
else{
if (true) {
console.log("The url is:" + req.url);
const path = req.url.split('/')[2]
console.log("Path:" + path);
var file = `./uploads/${path}`
var range = req.headers.range;
fs.stat(file, function(err, stats) {
var total = stats.size;
if(range){
console.log('RANGE: ' + range);
var positions = range.replace(/bytes=/, "").split("-");
var start = parseInt(positions[0], 10);
var end = positions[1] ? parseInt(positions[1], 10) : total - 1;
var chunksize = (end - start) + 1;
console.log(req.url, start, end);
res.writeHead(206, {
"Content-Range": "bytes " + start + "-" + end + "/" + total,
"Accept-Ranges": "bytes",
"Content-Length": chunksize,
"Content-Type": "video/mp4"
});
fs.createReadStream(file, { start: start, end: end }).pipe(res);
} else {
res.writeHead(200, { 'Content-Length': total, 'Content-Type': 'video/mp4' });
fs.createReadStream(file).pipe(res);
res.render('videos', {videoData:result})//Erro: can't set header after they're sent
}
});
} else {
console.log(req.url + ' (static)');
next();
}
}
})
})
app.get('/', function(req, res){
Video.find({}, function(err, result){
if(err){
console.log(err);
}
else{
console.log();
res.render('home', {videoData:result})
}
})
})
app.post('/upload', uploadVideo, newVideo)
app.listen(3000, ()=>{
console.log("Server running on port 3000")
})
You can't use both
res.writeHead();
and
res.render();
Read more: Error: Can't set headers after they are sent to the client
how to get an image from android?
I used console.log(request.files.image.originalFilename);
how to read the image in nodejs server.
console.log(request.files.image.path);
can anyone give the solution how to get the file and how to read the file?.
I got an error image is not defined.
var express=require("express");
var app=express();
var multer=require("multer");
var path=require("path");
var fs=require("fs");
var bodyparser=require("body-parser");
var urlencoded=bodyparser.urlencoded({extended:false});
app.use(bodyparser.json({limit: "50mb"}));
app.use(bodyparser.urlencoded({limit: "50mb", extended: true,parameterLimit:50000}));
app.post("/uploadimage",urlencoded,function(request,response)
{
console.log("I got a request");
console.log(request.files.image.originalFilename);
fs.readFile(request.files.image.path,function (err, data)
{
var dirname = "C:/Users/Kishore Baskar/WebstormProjects/Confident";
var newPath = dirname + "/imagesfolder/one.jpg";
fs.writeFile(newPath, data, function (err)
{
if (err)
{
console.log("file not written");
}
else
{
console.log("file written successfully");
}
});
});
});
app.listen(8086,function()
{
console.log("server listen at port 8086");
});
import multer from 'multer';
// Where you want to store file locally
var storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, './uploads/');
},
filename: function(req, file, cb) {
cb(null, file.originalname)
}
})
try{
var upload = 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(new Error('Only images are allowed'))
}
callback(null, true)
},
limits:{
fileSize: 1024 * 1024
}
});
} catch(e){
console.log("Error File in file Upload Filter",e);
}
**//storage: storage }).single('file') file is file name object like : file:fileobject from client**
router.post('/uploadImage',multer({ storage: storage }).single('file'),(req,res,next) => {
try {
// Get File Here
console.log(req.file);
} catch(e){
console.log(e)
}
I want to upload my file in my workspace and read it in node.js.
Html code:
<html>
<head>
<script src = "http://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
</head>
<body>
<div ng-app="" ng-controller="SalesImportControl">
<form ng-submit="readCustomer()">
<input type="file" name="file" file-model = "myFile">
<br>
<button type="submit" >Submit</button>
</form>
</div>
</body>
</html>
Controller:
'use strict';
angular.module('app')
.controller('SalesImportControl', ['$scope','$http', '$location', '$rootScope','fileUpload' , function($scope, $http, $location, $rootScope,fileUpload) {
console.log(" In dataimportCtrl");
//customer
$scope.readCustomer = function(req,res){
var file1=$scope.myFile;
var fl1 = $scope.myFile.name;
console.log("file name:"+$scope.myFile.name);
var uploadUrl = "/fileUpload";
var fd = new FormData();
fd.append('file', file1);
//File upload
$http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
}).success(function(data){
}).error(function(){
});
//sales
$http.post('/salesimport', { params: fl1 }).success(function(data) {
console.log("in controller1");
console.log("controller:"+data);
$scope.data=data["jarr"];
$scope.data1=data["jarr1"];
$scope.data2=data["jarr2"];
$scope.data3=data["jarr3"];
$scope.data4=data["jarr4"];
}).error(function(response) {
console.error("error in posting");
});
};
}])
Server.js:
var express = require('express');
var bodyparser = require('body-parser');
var mysql = require('mysql');
var app = express();
var formidable = require('formidable');
var path = require('path');
var fs = require('fs');
var _ = require('underscore');
var vouchersmodel = require('./models/v_db.js');
app.use(express.static(__dirname + "/public/angular"));
app.use(bodyparser.json());
app.listen(3000);
console.log('Server running on 3000');
app.post('/fileUpload', function (req, res) {
var form = new formidable.IncomingForm();
//Formidable uploads to operating systems tmp dir by default
form.uploadDir = __dirname+"/models/upload2/"; //set upload directory
form.keepExtensions = true; //keep file extension
form.parse(req, function(err, fields, files) {
res.writeHead(200, {'content-type': 'text/xml'});
res.write('received upload:\n\n');
console.log("form.bytesReceived");
console.log("file size: "+JSON.stringify(files.file.size));
console.log("file path: "+JSON.stringify(files.file.path));
console.log("file name: "+JSON.stringify(files.file.name));
console.log("file type: "+JSON.stringify(files.file.type));
console.log("astModifiedDate:"+JSON.stringify(files.file.lastModifiedDate));
console.log("file:"+JSON.stringify(files.file));
vouchersmodel.upload(files.file.path,files.file.name, function (msg) {
return res.json(msg);
});
});
});
Model:
exports.upload= function(r,name,callback){
var fs = require('fs');
var newPath = __dirname + "/upload2/"+name;
fs.readFile(r, function (err, data) {
fs.writeFile(newPath,data, function (err,res) {
if(!err){
console.log("uploaded.........");
callback();
}
});
});
}
My question is it uploads the file but before uploading the file it runs the salesimport post method in controller and shows no such directory error.
Where I am wrong ?
Note:
salesimport post method request accesses the file uploaded in model.