Could you please tell me how to download server file in node js
here is my code
Node js code (request code)
var express = require('express');
var multer = require('multer');
var bodyParser = require('body-parser');
var cors = require('cors');
var app = express();
var path = require('path');
var PORT = process.env.PORT || 3000;
// use of body parser
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
app.use(cors());
app.get('/download', function(req, res){
console.log(__dirname);
var file = path.join(__dirname , '/uploads/file-1534458777206.xlsx');
console.log(file)
res.download(file); // Set disposition and send it.
});
app.listen(PORT, () => {
console.log(`App is listening to ${PORT}`);
})
I am requesting like that on client
$('.download').on('click', function () {
$.ajax({
url: 'http://localhost:3000/download',
type: 'GET',
dataType: 'json',
success: function (data) {
console.log('data')
},
error: function (jqXHR, textStatus, errorThrown) {
// Handle errors here
console.log('ERRORS: ' + textStatus);
// STOP LOADING SPINNER
}
});
getting error on console
ERRORS: parsererror
3index.html?_ijt=9lu9erpan2oq6qf28851ngj0ra:32 ERRORS: parsererror
2index.html?_ijt=9lu9erpan2oq6qf28851ngj0ra:32 ERRORS: parsererror
server logs
C:\Users\B0207296\WebstormProjects\uploadFile\server
C:\Users\B0207296\WebstormProjects\uploadFile\server\uploads\file-1534458777206.xlsx
why files is not download on client as I mention file is present in above url
To get the file content via ajax:
Just remove the dataType, your file is being parsed to json causing the error.
$('.download').on('click', function () {
$.ajax({
url: 'http://localhost:3000/download',
type: 'GET',
success: function (data) {
console.log(data); // File data
},
error: function (jqXHR, textStatus, errorThrown) {
// Handle errors here
console.log('ERRORS: ' + textStatus);
// STOP LOADING SPINNER
}
});
To download the file is better user a virtual link
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
<b class="download">Download Here</b>
<script>
$('.download').on('click', function () {
var link = document.createElement('a');
link.href = 'http://localhost:3000/download';
var e = document.createEvent('MouseEvents');
e.initEvent('click', true, true);
link.dispatchEvent(e);
})
</script>
</body>
</html>
Related
My node.js code looks like this:
var connect = require('connect');
var serveStatic = require('serve-static');
connect().use(serveStatic("WebDir")).listen(80, function(){
console.log('Server running on port 80...');
});
I would like to use an API and use the data from the input field in node.js
How can i exactly do it. The Input field is just a normal input field in HTML
You can create a simple test setup for this using Node.js Express..
2 files: index.js, index.html
index.html
<html>
<head>
<script src="https://code.jquery.com/jquery-3.3.1.js"></script>
<script type="text/javascript">
var sendInput = function() {
var inputField = $('#inputField').val();
console.log(inputField);
$.ajax({
type: 'POST',
url: 'http://localhost:3000/inputData',
crossDomain: true,
data: JSON.stringify({ inputField: inputField }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(result, status){
document.getElementById("output").innerHTML = result.nodeVariable;
},
error: function (errorMessage) {
console.error('Error: ', errorMessage);
}
});
}
</script>
</head>
<body topmargin="40" leftmargin="40">
<div id="result">Loading..</div>
</br>
<button onClick="sendInput()">Send input to Node.js</button> : <input type="text" id="inputField" value="test value"><br>
<div>
<br/>Result: <p id="output"></p>
<div>
</body>
</html>
Server side, this is the node.js script.
index.js
const bodyParser = require('body-parser');
const express = require('express');
const port = (process.env.PORT || 3000);
const app = express();
app.use(express.static(__dirname));
app.use(bodyParser.json());
app.post('/inputData', (req, res, next) => {
console.log('/inputData post: ', JSON.stringify(req.body));
// Read the variable..
var inputField = req.body.inputField;
console.log('Input field: ', inputField);
res.status(201).send(JSON.stringify({status: 'OK', nodeVariable: inputField + " - updated by node."}))
});
app.listen(port);
console.log('Express listening on port ' + port);
Go to http://localhost:3000 on your browser to test.
when pressing a button this code gets executed
function submitData() {
$.ajax({
type: 'GET',
url: '/questionnaire/submit', // listen to a route
dataType: "json",
data: JSON.stringify({ // some test data
satisfactory: "house",
improvement: "bla",
rating: "this is a text"
})
}).done(function () {
$(location).attr('href', '/sendOff'); // redirect to another route
}).fail(function () {
console.log("Error");
});
}
and the server is listening on this
app.get('/questionnaire/submit', function (req, res) {
var data = req.query; // Get the data object from the Ajax call
console.log(data);
res.send(null); // Send nothing back
});
Whenever pressing the button, "Error" gets logged in the console. The Ajax call always fails.
Even when writing res.send("Success"); the client will log "Error". What am I missing?
Update:
I installed the body parser middleware and use this code now
my app.js
const path = require('path');
const express = require('express');
const exphbs = require('express-handlebars');
const bodyParser = require('body-parser');
const handlebars = exphbs.create({
defaultLayout: 'index',
extname: 'hbs'
});
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
require('./Server/Routes/questionnaire')(app);
require('./Server/Routes/sendOff')(app);
app.engine('hbs', handlebars.engine);
app.set('view engine', 'hbs');
app.use(express.static(path.join(__dirname, 'Public')));
app.listen(8888, function () {
console.log('Server running on port 8888');
});
my route
module.exports = function (app) {
app.get('/questionnaire', function (req, res) {
res.render('questionnaire');
});
app.post('/questionnaire/submit', function (req, res) {
var data = req.body;
console.log(data);
res.send(null);
});
};
and my client function
function submitData() {
$.ajax({
type: 'POST',
url: '/questionnaire/submit',
dataType: "json",
data: JSON.stringify({
satisfactory: $("#edtSatisfactory").val(),
improvement: $("#edtImprovement").val(),
rating: currentRating / ratingElements.length
})
}).done(function () {
$(location).attr('href', '/sendOff');
}).fail(function () {
});
}
And when executing the Ajax call the client still runs into .fail()
Client request is :
function submitData() {
$.ajax({
type: 'POST',
url: '/questionnaire/submit', // listen to a route
dataType: "json",
data: {
satisfactory: "house",
improvement: "bla",
rating: "this is a text"
}
}).done(function () {
$(location).attr('href', '/sendOff'); // redirect to another route
}).fail(function () {
console.log("Error");
});
}
and the server is listening on this Using bodyParser middleware in your node backend
:
app.post('/questionnaire/submit', function (req, res) {
var data = req.body; // Get the data object from the Ajax call
console.log(data);
res.end(); // Send nothing back
});
You're using a GET http method, which shouldn't take body, you should instead append your data to the back of the url. Or if you want to use a body, then switch to a POST.
url: '/questionnaire/submit?satisfactory=house&improvement=bla&rating=sometext
If you're using POST don't forget:
'Content-Type': 'application/json',
Edit: On the server you need to parse the JSON request, this is best done with a middleware called body-parser:
npm install --save body-parser
const bodyParser = require('body-parser');
app.use(bodyParser.json());
This will parse your JSON and add it to req.body.
Try this..
Client Side
function submitData() {
$.ajax({
type: 'POST',
url: '/questionnaire/submit', // listen to a route
'Content-Type': 'application/json',
data: JSON.stringify({"satisfactory": "house", "improvement": "bla", "rating": "this is a text"})
}).done(function () {
console.log('hi')
}).fail(function () {
console.log("Error");
});
}
On server Side:
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.json());
app.post('/questionnaire/submit', function (req, res) {
var data = req.body
console.log(data);
res.send(null); // Send nothing back
});
You have to install body-parser library using following command.
npm install --save body-parser
It will log "Hi" as ajax done is called. BTW You have redirected the page to 'sendOff' in your question.
If you are not understanding anything plz comment below.
You just have to replace
dataType: "json",
with this:
'Content-Type': 'application/json'
in $.ajax request
Hope this will work.. I have tried & tested.
I can successfully send a file to connect-busboy by using an HTML form's action attribute like so:
<form ref='uploadForm' method="post" action="http://localhost:3000/fileupload" enctype="multipart/form-data" id='uploadForm'>
Select file to upload:
<input type="file" name="sampleFile">
<input type="submit" value="Upload!">
</form>
However, I would prefer to not have my page redirect.
I tried to convert this to jQuery by removing the action attribute in the form tag and adding an onclick function with the following:
$.ajax({
url:'http://localhost:3000/fileupload',
type:'post',
contentType: 'multipart/form-data',
data:$('#uploadForm').serialize(),
success:function(){
alert('Success');
},
error: function() {
alert('Error');
},
});
Unfortunately, this doesn't work with the error:
TypeError: Cannot read property 'end' of undefined
The Nodejs code is as follows:
const express = require('express');
const busboy = require('connect-busboy');
const app = express();
app.use(busboy());
const fs = require('fs');
app.post('/fileupload', function(req, res) {
var fstream;
req.pipe(req.busboy);
req.busboy.on('file', function (fieldname, file, filename) {
console.log("Uploading: " + filename);
fstream = fs.createWriteStream(__dirname + '/files/' + filen ame);
console.log(fstream);
file.pipe(fstream);
fstream.on('close', function () {
res.send('Success');
});
});
});
var port = process.env.PORT || 3000;
app.listen(port);
Full error: http://i.imgur.com/vUqmjWS.png
By explicitly serializing the form you are implicitly avoiding/removing the multipart/form-data format. Instead, pass a FormData instance as the data. You can instantiate a new FormData from an existing form like:
var data = new FormData($('#uploadForm')[0]);
$.ajax({
url: 'http://localhost:3000/fileupload',
type: 'POST',
contentType: false,
processData: false,
cache: false,
data: data,
success: function() {
alert('Success');
},
error: function() {
alert('Error');
}
});
I've followed multiple tutorials to set up socketio-jwt, but every time it seems that I'm not getting past this part:
Connected to SocketIO, Authenticating
Any ideas?
Client side:
<h1>Socket Connection Status: <span id="connection"></span></h1>
<script type="text/javascript">
$(document).ready(function () {
socketIOConnectionUpdate('Requesting JWT Token from Laravel');
$.ajax({
url: 'http://localhost:8000/token?id=1'
})
.fail(function (jqXHR, textStatus, errorThrown) {
socketIOConnectionUpdate('Something is wrong on ajax: ' + textStatus);
})
.done(function (result, textStatus, jqXHR) {
socketIOConnectionUpdate('Connected to SocketIO, Authenticating')
/*
make connection with localhost 3000
*/
var token = result.token;
var socket = io.connect('http://localhost:3000');
socket.on('connect', function () {
socket
.emit('authenticate', {token: token}) //send the jwt
.on('authenticated', function () {
console.log('authenticated');
socketIOConnectionUpdate('Authenticated');
})
.on('unauthorized', function(msg) {
socketIOConnectionUpdate('Unauthorized, error msg: ' + msg.message);
throw new Error(msg.data.type);
})
});
});
});
/*
Function for print connection message
*/
function socketIOConnectionUpdate(str) {
$('#connection').html(str);
}
Server side
var express = require('express');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var socketioJwt = require('socketio-jwt');
var dotenv = require('dotenv').config({path:'../.env'});
var port = 3000;
io
.on('connection', socketioJwt.authorize({
secret: dotenv.JWT_SECRET,
timeout: 100 // 15 seconds to send the authentication message
}))
.on('authenticated', function(socket){
console.log('connected & authenticated: ' + JSON.stringify(socket.decoded_token));
socket.on('chat message', function(msg){
debugger;
io.emit('chat message', msg);
});
});
http.listen(port, function(){
console.log('listening on *:' + port);
});
You may have misunderstood how dotenv works, as you're trying to use it's return value.
Dotenv is a zero-dependency module that loads environment variables from a .env file into process.env.
From: dotenv github
Instead, it exports the variables stored in the file located at ../.env as environment variables, that become available as a part of process.env.
So instead of this:
var dotenv = require('dotenv').config({path:'../.env'});
socketioJwt.authorize({
secret: dotenv.JWT_SECRET,
timeout: 100
})
Do this
// do this near the entry point to your application!!
require('dotenv').config({path:'../.env'});
socketioJwt.authorize({
secret: process.env.JWT_SECRET,
timeout: 100
})
I get the error - "Cannot read property 'score' of undefined" at "var score - req.body.score". In order to do this I'm guessing I need to define and/or initialise 'req.body' (I'm pretty new to Node.js), any idea how I do this?
Here's my Node.JS code as it stands:
var http = require('http');
var express = require('express');
console.log('Game server running...');
http.createServer(function (req, res) {
console.log('Player submitted high-score:');
var score = req.body.score;
console.log(score);
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('_testcb(\'"Your high-score has been submitted."\')');
}).listen(80);
Below is the HTML with the input text field and a submit button:
Your score: <input id="score" name="score" type="text"></input>
<button id="SubmitBtn" type="submit">Submit</button>
And also below is the JavaScript within the HTML (Just in case it helps answer my question):
<script>
$(document).ready(function() {
$('#SubmitBtn').click(function (event) {
$.ajax({
url: 'http://localhost',
data: { score : $("input[name='score']").val() },
dataType: "jsonp",
jsonpCallback: "_testcb",
cache: false,
timeout: 5000,
success: function(data) {
$("#test").append(data);
},
error: function(jqXHR, textStatus, errorThrown) {
alert('Error connecting to the Node.js server... ' + textStatus + " " + errorThrown);
}
});
});
});
Basically, I want to get the input from a input text field called 'score' from a HTML doc, but getting the error "Cannot read property 'score' of undefined" at 'var score - req.body.score'. Guessing I need to initialise/define 'req.body somewhere but I don't know how? Can anyone help me out?
Also, I've found this online about initialising/defining 'res.body', could be useful??
req.on('response', function (res) {
res.body = "";
res.on('data', function (chunk) {
res.body += chunk;
});
res.on('end', function () {
console.log(res.body);
});
});
Thanks
I don’t know whether some “middleware” provides req.body, but to continue down that path:
var http = require('http');
var express = require('express');
var qs = require('querystring');
console.log('Game server running...');
http.createServer(function (req, res) {
console.log('Player submitted high-score:');
var bodyParts = [];
req.on("data", function(part) {
bodyParts.push(part);
});
req.on("end", function() {
var body = Buffer.concat(bodyParts).toString("utf8");
var data = qs.parse(data);
var score = data.score;
console.log(score);
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('_testcb(\'"Your high-score has been submitted."\')');
});
}).listen(80);
The request.body property is populated by the bodyParser middleware, so you have to include that in the node.js app as well
app.use(express.bodyParser())
so
var http = require('http');
var express = require('express');
var app = express();
console.log('Game server running...');
app.use(express.bodyParser())
console.log('Player submitted high-score:');
app.get('/', function(req, res) {
var score = req.body.score;
console.log(score);
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('_testcb(\'"Your high-score has been submitted."\')');
});
app.listen(80);
req is the request, containing data from the current request, and res is the response you send back from the server, so trying to get the data from the input from the respone you send back is not going to work.