Getting html form data using http - html

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...

Related

How to download a file on Client side using nodejs

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);

What does the URL argument do in the xhr.open() function?

I am writing some server software, and I have tested it using a very simple HTML file. It doesn't seem to make any difference what the URL argument is when I open a new XMLHttpRequest POST request. Can anyone tell me? Here is the code if it helps:
Browser HTML file:
<!DOCTYPE html>
<html>
<body>
<title>This is a title!</title>
<p id="paragraph">
Hello World!
</p>
<script>
setTimeout(() => {
var http = new XMLHttpRequest();
var jsonToSend = {
"name": "Steve Smith",
"age": 25,
"isMale": true
};
http.open("POST", "", true);
http.setRequestHeader("Content-Type", "application/json");
http.send(JSON.stringify(jsonToSend));
}, 3000);
</script>
</body>
</html>
Server code (node.js)
const http = require("http");
const fs = require("fs");
const port = 80;
http.createServer((request, response) => {
if (request.method == "GET") {
try {
var newUrl = request.url.substring(1);
if (request.url == "/") {
newUrl = "test.html";
}
response.writeHead(200, "OK", {"Content-Type": "text/html"});
response.write(fs.readFileSync(newUrl).toString());
} catch (error) {
response.writeHead(404, "Not Found", {"Content-Type": "text/html"});
response.write("<h1>404 not found</h1>");
}
response.end();
} else if (request.method == "POST") {
var body = "";
request.on("data", (chunk) => {
body += chunk.toString();
});
request.on("end", () => {
console.log(JSON.parse(body));
response.statusCode = 200;
response.end(body);
});
}
console.log(request.method + ":");
console.log(" URL: " + request.url);
console.log(" Status code: " + response.statusCode);
}).listen(port, () => {
console.log("Listening on port " + port);
});
It sets the URL the request is made to.
It only doesn't seem to make a difference because you're written a webserver which doesn't pay attention to the URL for POST requests.

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>

cors unexpected end of JSON input

I am parsing my json on end but I am still receiving this error.
'use strict';
const http = require('http');
const tools = require('./tools.js');
const server = http.createServer(function(request, response) {
console.log("received " + request.method + " request from " + request.headers.referer)
var body = "";
request.on('error', function(err) {
console.log(err);
}).on('data', function(chunk) {
body += chunk;
}).on('end', function() {
console.log("body " + body);
var data = JSON.parse(body); // trying to parse the json
handleData(data);
});
tools.setHeaders(response);
response.write('message for me');
response.end();
});
server.listen(8569, "192.168.0.14");
console.log('Server running at 192.168.0.14 on port ' + 8569);
Data being sent from the client:
var data = JSON.stringify({
operation: "shutdown",
timeout: 120
});
I successfully receive the json but I am unable to parse it.
Update:
I've updated the code to include the server code in its entirety.
To be perfectly clear, using the following code:
....
}).on('end', function() {
console.log("body " + body);
var json = JSON.parse(body); // trying to parse the json
handleData(json);
});
I get this:
However, this:
....
}).on('end', function() {
console.log("body " + body);
//var json = JSON.parse(body); // trying to parse the json
//handleData(json);
});
produces this
Can we see the server code, please?
Here is a working end-to-end example which is (more or less) what you are attempting, I believe.
"use strict";
const http = require('http');
/********************
Server Code
********************/
let data = {
operation: 'shutdown',
timeout: 120
};
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.write(JSON.stringify(data));
res.end();
});
server.listen(8888);
/********************
Client Code
********************/
let options = {
hostname: 'localhost',
port: 8888,
path: '/',
method: 'POST',
headers: {
'Accept': 'application/json'
}
};
let req = http.request(options, res => {
let buffer = '';
res.on('data', chunk => {
buffer += chunk;
});
res.on('end', () => {
let obj = JSON.parse(buffer);
console.log(obj);
// do whatever else with obj
});
});
req.on('error', err => {
console.error('Error with request:', err);
});
req.end(); // send the request.
It turns out that as this is a cross-origin(cors) request, it was trying to parse the data sent in the preflighted request.
I simply had to add an if to catch this
....
}).on('end', function() {
if (request.method !== 'OPTIONS') {
var data = JSON.parse(body);
handleData(data);
}
});
Further reading if you're interested: HTTP access control (CORS)
Put the identifiers in quotes.
{
"operation": "shutdown",
"timeout": 120
}
http://jsonlint.com/ Is a helpful resource.