How to download a file on Client side using nodejs - html

I am pretty new to nodejs basically I am trying to send a file saved on my laptop to the client to download.The file is saved in the same folder as app.js(filename of nodejs file).When I am executing this code it is giving
TypeError: res.download is not a function.
Please suggest a way so that I can implement this.
PS: I have also tried writing res.download('/filtered_database.csv'); but same error is coming up.
Nodejs code:
const http = require('http');
const express = require('express')
const {spawn} = require('child_process');
const app = express()
const port = 5000
const server = http.createServer((req, res) => {
if (req.method === 'POST') {
let body = '';
req.on('data', chunk => {
body += chunk.toString(); // convert Buffer to string
});
req.on('end', () => {
console.log(body);
const express = require('express')
const {spawn} = require('child_process');
app.get('/', (req, res) => {
var dataToSend;
// spawn new child process to call the python script
//console.log('Start')
const python = spawn("python", ["filter.py",body]);
// collect data from script
python.stdout.on('data', function (data) {
console.log('Pipe data from python script ...');
dataToSend = data.toString();
});
// in close event we are sure that stream from child process is closed
python.on('close', (code) => {
console.log(`child process close all stdio with code ${code}`);
// send data to browser
res.send(dataToSend)
});
})
app.listen(port, () => console.log(`Example app listening on port
${port}!`))
res.writeHead(301,
{ Location: 'http://127.0.0.1:5000' }
);
res.download(__dirname + 'filtered_database.csv', 'filtered_database.csv');
//res.attachment('filtered_database.csv');
res.end();
});
}
else {
res.end(`
<!doctype html>
<html>
<body>
<style>
body, html {
height: 100%;
}
body {
background-image: url('https://mcdn.wallpapersafari.com/medium/38/26/KlxIwM.jpg');
height: 100%;
/* Center and scale the image nicely */
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
</style>
<center>
<h3>WELCOME TO THE POSTCODE MAPPING TOOL</h3>
<form action="/" method="post">
<label>Enter Country</label><input type="text" name="Country" /><br />
<label>Enter City </label><input type="text" name="City" /><br />
<label>Enter State </label><input type="text" name="State" /><br />
<a href="http://127.0.0.1:5000">
<button>Generate CSV file</button>
</a>
</form>
</center>
</body>
</html>
`);
}
});
server.listen(3000);

Try this
const http = require('http'),
fileSystem = require('fs'),
path = require('path');
http.createServer(function(request, response) {
const filePath = path.join(__dirname, '/filtered_database.csv');
const stat = fileSystem.statSync(filePath);
response.writeHead(200, {
'Content-Type': 'text/csv',
'Content-Length': stat.size
});
const readStream = fileSystem.createReadStream(filePath);
readStream.pipe(response);
})
.listen(8080);

Related

NodeJs Try to evaluate a HTML Form

I've an problem with evaluating an HTML Form using NodeJs and express.
This is my Java Script Code
My goal is to handle HTML Form in nodeJs using express.
const express = require('express');
const http = require('http');
const fs = require('fs');
const app = express();
var warehouses = [];
app.use(express.urlencoded({extended: true}));
app.use("/warehouse", (req, res, next) => {
fs.readFile("./addWarehouse.html", function(err, data) {
res.write(data);
next();
});
});
app.post("/warehouse/add", (req, res) => {
console.log("ADDED");
// warehouses.push(req.body.nWarehouse);
console.log('Request Type:', req.method);
res.end;
});
app.listen(8080);
And this is my HTML Form
<!DOCTYPE html>
<!-- <head>
<meta charset="utf-8" />
<title>Coole Seite</title>
</head> -->
<body>
<h1>Warehouses</h1>
<form method='POST' action="/warehouse/add">
<input type="text" name="nWarehouse" id="nWarehouse"/>
<input typse="submit" value="bitte sende" />
</form>
</body>
</html>
I tried to debug it with the console output and I figured out that it never access the app.use("/submit/add/" ... " part.
I would be happy to get some advice.
Here if the intent is to evaluate the form that is there in addWarehouse.html which should render when you go to /warehouse and the form should submit to /warehouse/add.
The middleware concept used via app.use(...) here is not required at all.
Express code:
const express = require('express');
const http = require('http');
const fs = require('fs');
const app = express();
var warehouses = [];
app.use(express.urlencoded({extended: true}));
//show addWareHouse.html for /warehouse
/* serving the HTML via fs */
app.get("/warehouse", (req, res, next) => {
fs.readFile("./addWarehouse.html", function(err, data) {
res.writeHead(200, { "Content-Type": "text/html" });
res.write(data);
res.end();
});
//add warehouse form submit for /warehouse/add
app.post("/warehouse/add", (req, res) => {
console.log("ADDED");
console.log("REQUEST PARAM::", req.body);
//do you adding of ware-house stuff here
console.log("Request Type:", req.method);
return res.end();
});
app.listen(8080, () => console.log(`app listening on port 8080!`));
Note:
There are other handy ways to serve views (HTML) in express like template engines, res.sendFile() etc.

How to download a file hosted on http webserver in nodejs

I have created a nodejs http webserver to host some files -
var http = require('http'),
fs = require('fs');
var finalhandler = require('finalhandler');
var serveStatic = require('serve-static');
var qs = require('querystring');
var serve = serveStatic("./");
fs.readFile('./index.html', function (err, html) {
if (err) {
throw err;
}
http.createServer(function(req, res) {
var done = finalhandler(req, res);
serve(req, res, done);
if(req.method === "POST") {
if (req.url === "/downloadInstaller") {
var requestBody = '';
req.on('data', function(data) {
requestBody += data;
if(requestBody.length > 1e7) {
res.writeHead(413, 'Request Entity Too Large', {'Content-Type': 'text/html'});
res.end('<!doctype html><html><head><title>413</title></head><body>413: Request Entity Too Large</body></html>');
}
});
req.on('end', function() {
fs1.readFile("./FileToDownload.zip", function(err, data)
{ res.statusCode = 200;
res.setHeader('Content-type', 'text/plain' );
res.write(data);
return res.end();
});
});
}
}
}).listen(8000);
});
Its working good . I can download a file when I hit url - http://localhost:8000/fileToDownload.extension
Now , my index.html looks like -
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<form action="/downloadInstaller" method="post">
<label>OS Flavor : </Label>
<input type="text" id="os" name="os"/>
<input type="submit"/>
</form>
I want to download same file when I will click on submit button.I have written the code for same. But it renders the file in browser instead of downloading it.
How Can i achieve it in nodejs?
Considerably new in nodejs.
Thanks
You should remove this :
res.setHeader('Content-type', 'text/plain' );
And replace it with headers hinting the browser that it should download the file:
res.setHeader('Content-Description', 'File Transfer');
res.setHeader('Content-Type', 'application/octet-stream');
res.setHeader('Content-Type', 'application/force-download'); // only if really needed
res.setHeader('Content-Disposition', 'attachment; filename=FileToDownload.zip');
NB: the "force-download" header is a dirty hack, try without it first.

How to handle file upload using sequelize + mysql + express js?

I'm developing a simple software college project that needs pdf/doc file upload. But here comes the bottleneck: I couldn't find anywhere an example and example of this feature using the Sequelize ORM.
Has anyone done something similar using this framework?
*By the way, I know there are several npm packages for express(), but I must use sequelize.
Any advice is welcome.
Thanks in advance ;)
Configure your express app with multer. Read over the documentation for multer, but in short you store the path of the uploaded file:
const multer = require('multer')
const express = require('express')
const Sequelize = require('sequelize')
const sequelize = new Sequelize('database', 'username', 'password')
const MyModel = sequelize.define('myModel', {
filePath: Sequelize.STRING,
})
const express = express()
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, './app/uploads')
},
filename: (req, file, cb) => {
cb(null, file.originalname)
}
})
app.post('/upload', multer({ storage }).single('example'), async (req, res) => {
// This needs to be done elsewhere. For this example we do it here.
await sequelize.sync()
const filePath = `${req.file.destination}/${req.file.filename}`
const myModel = await MyModel.create({ filePath })
})
A slightly simpler example (from) using AJAX.
Add to your node.js
var multer = require('multer');
const storage = multer.diskStorage({
destination: (req, file, callback) => {
console.log(req);
callback(null, './uploads');
},
filename: (req, file, callback) => {
console.log(req);
callback(null, Date.now() + file.originalname);
}
});
var upload = multer({storage:storage}).single('myFile');
app.post('/dashboard/myFile', function(req,res){
upload(req,res,function(err){
//console.log("owen",req.file,err);
if (err)
return res.end("error uploading file");
res.end("file is uploaded");
});
});
And in your HTML
<form id="myForm" name="myForm" enctype="multipart/form-data" method="post">
<input id="myFile" name="myFile" type="file">
<button type="submit" class="btn btn-primary">Submit</button>
</form>
<script>
var form = document.forms.namedItem("myForm");
form.addEventListener('submit', function(ev){
var myFile = document.getElementById('myFile').files[0];
var oData = new FormData(form);
var oReq = new XMLHttpRequest();
oReq.open("POST","/uploadFile",true);
oReq.onload = function(oEvent){
if(oReq.status == 200) {
console.log("success",oEvent);
} else {
console.log("fail",oEvent);
}
}
oReq.send(oData);
ev.preventDefault();
},false);
</script>

Getting html form data using http

I need to get data from simple html form (code below) and send it to API (http://netology.tomilomark.ru/doc/#api-ND) that makes hash out of it.
Here is html form code:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Form</title>
</head>
<body>
<form action="/sendForm">
Name:<br>
<input type="text" name="firstName" value="">
<br>
Surname:<br>
<input type="text" name="lastName" value="">
<br><br>
<input type="submit" value="Send">
</form>
</body>
And that's what I´ve got on the server side:
"use strict";
const http = require("http");
const fs = require("fs");
const PORT = 3000;
let resObject = {};
let hash;
// Code that sends name + surname to the API and creates hash
// ------------- begin -------------
let options = {
hostname: "netology.tomilomark.ru",
path: "/api/v1/hash",
method: "POST",
headers: {
"firstName": "Evgeny",
"Content-Type": "application/json"
}
};
let req = http.request(options, (res) => {
let resString = "";
res.on("data", (data) => {
resString += data;
});
res.on("end", () => {
console.log(resString);
hash = resString["hash"];
})
});
let reqMessage = JSON.stringify({"lastName": "Kobzev"});
req.write(reqMessage);
req.end();
resObject.firstName = "Evgeny";
resObject.lastName = "Kobzev";
console.log(JSON.stringify(resObject));
// -------------- end --------------
// Create web server that loads the html file
// ------------- begin -------------
const server = http.createServer((req, res) => {
fs.readFile("./logs/form.html", (err, file) => {
res.writeHead(200, {'Content-Type': 'text/html','Content-Length':file.length});
res.write(file);
});
});
server.on("error", (err) => console.error(err));
server.on("listening", () => console.log(`Start HTTP on port ${PORT}`));
server.listen(PORT);
// -------------- end --------------
How can I get data from that simple form and later send it to API? The problem is that I need to use a low level abstraction solution: http and maybe querystring.
Any help will be appreciated!
After working for few minutes I get the code.Here in my code I am printing hash values in terminal.And here is my code
var qs = require('querystring');
var request=require('request');
var util=require('util');
const http= require("http");
const fs= require("fs");
var hash=require('object-hash');
const server = http.createServer((req, res) => {
if (req.url === '/sendForm' && req.method === 'POST') {
var body = "";
req.on('data', function (chunk) {
body += chunk;
});
req.on('end', function () {
var post= qs.parse(body);
var Fs=hash({NAME:post.firstName});
var Sn=hash({SURNAME:post.surName});
console.log("FirstName:"+post.firstName);
console.log("SurName:"+post.surName)
console.log("Hashed Value Of FirstName:"+Fs);
console.log("Hashed Value Of SurName:"+Sn);
res.end("successfully submitted");
});
}
fs.readFile("./sample.html", (err, file) => {
res.writeHead(200, {'content-type': 'text/html','Content-Length':file.length});
res.end(file);
});
}).listen(3000,function(){
console.log("Server Listening on 3000");
});
Hope this helps for you...

How to read image from HTML file with NodeJS?

I want to read an HTML file.
My HTML content:
<html>
<hear>
<title>Learn NodeJS</title>
</head>
<body>
<center>
<h1>Learn NodeJS with Khuong Pham</h1>
<img width="400" src="/nodejs.png" />
</center>
</body>
</html>
I've tried:
const http = require('http')
const fs = require('fs')
const express = require('express')
const app = express()
const folderPath = __dirname + '/public_files'
app.use(express.static(folderPath))
http.createServer(function(request, response) {
var filePath = folderPath + '/index.html'
console.log(filePath)
fs.access(filePath, fs.F_OK | fs.R_OK, function(err) {
if (err) {
response.writeHead(404, { 'Content-Type' : 'text/html' })
response.end('<h1>File not found</h1>')
} else {
fs.readFile(filePath, function(err, contentFile){
if (!err) {
response.writeHead(200, { 'Content-Type' : 'text/html' })
response.end(contentFile)
} else {
response.writeHead(500, { 'Content-Type' : 'text/html' })
response.end('<h1>Can not read this content</h1>')
}
})
}
})
}).listen(3500)
But when I access http://localhost:3500/, it says:
You are mixing two methods here. Firstly you are trying to use express, but later you are starting your own server using http.createServer Instead you should use express to do so.
Your js should be something similar to below. Have not tested below code. Edit it approiately. This is just to show the idea.
const http = require('http')
const fs = require('fs')
const express = require('express')
const app = express()
const folderPath = __dirname + '/public_files'
//mount your static paths
// renders your image and index.html
app.use(express.static(folderPath))
// renders your index.html
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname + '/index.html'));
});
//mount your other paths
// in this case render 404.
app.get("*",function (req, res) {
res.status(404).send(''<h1>File not found</h1>'');
});
//start the server.
app.listen(3500, function () {
console.log('Example app listening on port 3500!');
});