I want to upload file using node.js , being new to it a tried to check if the file is being send to server.
html
<html>
<head>
<title>File Uploading Form</title>
</head>
<body>
<h3>File Upload:</h3>
Select a file to upload: <br />
<form action="img" method="POST"
enctype="multipart/form-data">
<input type="file" name="file" size="50" />
<br />
<input type="submit" value="Upload File" />
</form>
</body>
</html>
js
var express = require("express");
var app=express();
var http=require("http").Server(app);
app.get("/",function(req,res){
res.end("hello")
});
app.get("/upload",function(req,res){
res.sendFile(__dirname + "/form.html")
})
app.post("/img",function(req,res){
if(req.files){
console.log(req.files.file.name);
}
else{
console.log("ee")
}
});
http.listen(3000,function(){
console.log("listening on 3000")
})
When i upload something , it throws error
Cannot read files of undefined
Being new to back end i have no idea why its happening , why doesnt the server recieve the file?
You need to app.use() a fileparser. For example, you could use connect-busboy. You can get more information about options and usage at above link; a simple setup would be somehting like this:
var busboy = require('connect-busboy');
app.use(busboy());
app.post("/img",function(req,res){
req.busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {
// ...
});
req.busboy.on('field', function (key, value, keyTruncated, valueTruncated) {
// ...
});
req.pipe(req.busboy);
// etc ...
});
As stated in the above answer, you must use a body parser for multipart bodies, but the better solution is to use the express middleware multer which lets you to use req.files just like in your OP.
Also, multer is built on top of busboy which is the fastest multipart body parser for node.js
With multer:
var express = require('express'),
multer = require("multer"),
app = express();
app.use(multer({
dest: path.resolve(__root + path.sep + config.get("localFolders").rawImages),
limits: {
files: 2
}
}));
// handle file upload
app.post("/img", function (req, res, next) {
var image = req.files.image;
// do something with image;
console.log(image.name);
});
Have a look on the documentation for multer within the link provided above. Good luck. :)
Related
(Please correct my terminology if it's not correct.)
My files server.js, run.js and index.html, are in the same directory.
server.js
Sets up the server.
const express = require('express');
const path = require('path');
const run = require('./run.js');
var app = express();
app.get('/index.html', function(req, res){
res.sendFile(path.join(__dirname + '/index.html'));
});
app.get('/', function(req, res){
res.redirect('index.html');
});
app.post('/run', async function(req, res){
var data = await run.run();
res.json(data);
});
app.listen(5000, function () {
console.log('Dev app listening on port 5000');
});
run.js
Will contain functions that consumes time. Here just one function as example:
async function run(){
//do time consuming stuff
var data = {
"status" : "ok",
"a1" : 1,
"a2" : 2
};
return data;
}
module.exports = {
run:run
}
index.html
Simple form.
<!DOCTYPE html>
<html>
<body>
<form id="search-form" action="/run" method="post">
Input:<br>
<input type="text" name="input1" id="input1" value = ""> <br>
<input type="submit" value = "Run">
</form>
<script></script>
<div id="data"></div>
</body>
</html>
When I run the server, go to localhost:5000 in the browser, and click the run button, I get redirected to a page just showing the content of data.
What I would like to happen when I click the the run button is;
The server process /run post request
A response is sent with res.json or res.send to the client
A javascript script on the client side should catch the response, process it, and make some change to the html code (in my case, create some table).
How can I achieve this?
So your problem is that you're using a form. Forms will redirect you to the specified web page with all of the form's data.
You need an XMLHttpRequest.
var xhr = new XMLHttpRequest();
xhr.open("POST", "/run", true);
xhr.send();
If you ever need the data of your form to be submitted as well, I have some documentation on how to do that.
Hope this helps!
I'm new to Node.js and JavaScript. I have a specific problem but mostly need advice on the best solution.
I'm running a Node server. I want the client to be able to submit a string to the server, then the server to display a new HTML page that shows the string data.
I'm using Express and Socket.io.
In the following files, the client sees index.html, then after submitting the form it sees return.html. I print the input string to the console, and the output is as expected (whatever the user enters). But the return.html is never updated with the input string.
I also tried sending the return.html page and the change_result call in an async series, but the sendFile function never ends and the second function in the series is never called. In previous attempts it worked intermittently with a setTimeout around the emit('change_result') function.
Why doesn't the call to change_result do anything? I used the same technique to update the headings of the original index.html in previous versions. Should I be routing to localhost.../return.html and sending the post data there, or something like that?
server.js
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var bodyParser = require('body-parser') //for POST request
app.use( bodyParser.json() ); // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({ // to support URL-encoded bodies
extended: true
}));
server.listen(8080, function() {
console.log("Server running on port 8080.");
});
var dir = __dirname;
app.get('/', function(req, res) {
res.sendFile(dir + '/index.html');
});
app.post('/', function(req, res) {
var query1=req.body.input1
console.log("Server: In post request.")
console.log(query1);
res.sendFile(dir + '/return.html');
io.emit('change_result', {
result: query1
});
});
index.html
<!DOCTYPE html>
<html>
<body id="body">
<form method="post" action="http://localhost:8080">
String: <input type="text" name="input1" id="input1" />
<input type="submit" id="button1" value="Submit" />
</form>
</body>
</html>
return.html
<!DOCTYPE html>
<html>
<body id="body">
<p id="heading1">Result: </p>
<script>
document.addEventListener('DOMContentLoaded', function() {
var socket = io();
socket.on('change_result', function(data) {
document.getElementById('heading1').innerHTML = "Result: \""+data.result"\"";
});
});
</script>
</body>
</html>
I'm not knee-deep inside socket.io, but IMO the problem is, that the server has no way to know if any listeners are ready.
I think you should emit a 'ready' event, once the return.html is loaded, then listen to 'change_result'. Also separate the socket communication from the POST response on the server. Like so.
server.js
var query;
app.get('/', function(req, res) {
res.sendFile(dir + '/index.html');
});
app.post('/', function(req, res) {
query = req.body.input1;
console.log("Server: In post request.");
console.log(query);
res.sendFile(dir + '/return.html');
});
io.on('connection', function(socket) {
socket.on('ready', function() {
socket.emit('change_result', {result: query});
});
});
return.html
<script>
document.addEventListener('DOMContentLoaded', function() {
var socket = io();
socket.emit('ready', function(data) {});
socket.on('change_result', function(data) {
document.getElementById('heading1').innerHTML = "Result: \""+data.result + "\"";
});
});
</script>
My code shows a simple upload form (node-formidable and node.js). I am using socket.io to update the client on it's current upload file progress. My problem is that I currently emit the progress update to every clients. As an example, if I start an upload with clientA, then connect to the website with clientB, clientB will see the exact same progress bar as clientA. Normally, clientA and clientB should be different, with their own respective progress bars, linked only with their respective uploads.
This is my app.js file
// Required modules
var formidable = require('formidable'),
http = require('http'),
util = require('util'),
fs = require('fs-extra');
// Path to save file, server side
var savePath = "./uploadedFiles/";
// Loading index.html
var server = http.createServer(function(req, res) {
// Form uploading Process code
//Upload route
if (req.url == '/upload' && req.method.toLowerCase() == 'post') {
// creates a new incoming form.
var form = new formidable.IncomingForm();
// set the path to save the uploaded file on server
form.uploadDir = savePath;
// updating the progress of the upload
form.on('progress', function(bytesReceived, bytesExpected) {
io.sockets.in('sessionId').emit('uploadProgress', (bytesReceived * 100) / bytesExpected);
});
// parse a file upload
form.parse(req, function (err, fields, files) {
res.writeHead(200, { 'content-type': 'text/plain' });
res.write('Upload received :\n');
res.end(util.inspect({ fields: fields, files: files }));
});
form.on('end', function (fields, files) {
/* Temporary location of our uploaded file */
var temp_path = this.openedFiles[0].path;
/* The file name of the uploaded file */
var file_name = this.openedFiles[0].name;
/* Files are nammed correctly */
fs.rename(temp_path, savePath + file_name, function(err) {
if ( err ) console.log('ERROR: ' + err);
});
});
return;
}
fs.readFile('./index.html', 'utf-8', function(error, content) {
res.writeHead(200, {"Content-Type": "text/html"});
res.end(content);
});
});
// socket.io
var io = require('socket.io').listen(server);
io.on('connection', function (socket) {
socket.join("sessionId");
});
server.listen(8080);
This is my index.html file
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Socket.io</title>
</head>
<body>
<h1>Test d'upload</h1>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost:8080');
socket.on('uploadProgress' , function (progress){
document.getElementById("currentProgress").value = progress;
});
</script>
<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="upload" multiple="multiple"><br>
<input type="submit" value="Upload">
</form>
<p><progress id="currentProgress" value="0" max="100"></progress></p>
</body>
</html>
I do not have more code than this. I am new to node.js and socket.io, so I am not sure about the interactions between them and between the client and server.
How can I change my code to update only the right client?
Thank you anyway for your time.
a suggestion
there is a basic way
socketIO.sockets.socket(this.socketid).emit(<event>, dataObj);
if your function is inside your socket code...otherwise I will often do something like this
connection.query("select socketid from websocket_sessions where user_id=" + data.form.user_id, function(err, users) {
socketIO.sockets.socket(users[0].socketid).emit(<event>, dataObj);
});
where I am always updating or a
index.html arrives on the browser by clicking a link called 'spons' from the home page "localhost:9000/" and the url changes to "localhost:9000/spons" , now when i submlit the form , it goes to the url "localhost:9000/spons/uploads" and gives "cannot POST /spons/uploads" , the images folder is in the same directory as the server.js file , can you please help me with this and suggest a solution ?
this is the index.html file
<form name='uploadform' enctype='multipart/form-data' method='post' action='/spons/uploads'>
<input name='imageupload' type='file'>
<input type="submit" value="Upload Image" name="submit">
</form>
this is the server.js file
var express = require('express');
var multer= require('multer');
var upload= multer({dest:'/images'}).single('imageupload');
var router = express.Router();
router.post('/spons/uploads', upload, function(req,res){
res.end('uploaded');
}
);
express().listen(9000);
You were getting cannot POST /spons/uploads, because you did not attach router to the app.
var express = require('express');
var app = express();
var multer= require('multer');
var upload= multer({dest:'/images'}).single('imageupload');
var router = express.Router();
router.post('/spons/uploads', upload, function(req,res){
res.end('uploaded');
});
app.use('/',router); // this line is the key.
app.listen(9000);
Hopes, it helps.
You don't even need explicit router, check the sample below
var express = require('express');
var app = express();
var multer= require('multer');
var upload= multer({dest:'/images'}).single('imageupload');
app.post('/spons/uploads', upload, function(req,res){
res.end('uploaded');
});
app.listen(9000);
I'm trying to get form data to node server using POST method.
This is my HTML code,
<html>
<head>
<title>
Node Architecture
</title>
</head>
<body>
<h1>Node Architecture</h1>
<h3>Enter Your name.</h3>
<form action="/" method="POST">
<input type="text" name="eventname" />
<input type="submit" value="Go" />
</form>
</body>
</html>
This is my node app, index.js
var app = require('express')();
var http = require('http').Server(app);
//var io = require('socket.io')(http);
//var qs = require('querystring');
app.get('/', function(req, res){
res.sendfile('index.html');
});
app.get('/events', function(req, res){
res.sendfile('events.html');
});
app.get('/movie', function(req, res){
res.sendfile('movie.html');
});
app.post('/', function(req, res) {
var name = req.body.eventname;
console.log(name);
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
Now when I click submit I get an error message which is as follows,
TypeError: Cannot read property 'eventname' of undefined at Object.handle
How do I print the entered name to my console?
Express doesn't parse request body by default, you will have to use a middleware to do that.
Try this.
var express = require('express');
var app = express()
.use(express.bodyParser());
...
...
Also, you should read this article. It explains some of the problems (and their solutions) related to common body parsing approach.
Add these lines into your app.js.
require body-parser.
var bodyParser = require('body-parser');
put before your first app.get that will be better.
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
good luck.