Extracting POST parameters from request in Nodejs - javascript

I am trying to get parameters from a POST in the variable postData by using the request by -
( i used this because it was suggested here - How do I get the post request with express js? )
and here -
How to retrieve POST query parameters?
var express = require('express');
var app = express();
var fs = require('fs');
var json = require('json');
app.use(express.json()); // to support JSON-encoded bodies
app.use(express.urlencoded()); // to support URL-encoded bodies
app.post('/shrib/:file/:data',function(req,res){
var fileName = req.params.file;
var data = req.params.data;
req.on('data',function(data){ body+=data; } );
req.on('end' ,function(){
var postData = qs.parse(body);
var writeStream = fs.createWriteStream(fileName);
var postData = req.body.text;
if(postData)
console.log(postData);
else
console.log("failed miserably");
res.write(200);
res.end();
});
});
app.get('/shrib/:file',function(req,res){
var fileName = req.params.file;
if(fileName != ''){
var readStream = fs.createReadStream(fileName);
var content;
readStream.on('data',function(chunk){
content+=chunk.toString();
console.log(content);
});
readStream.on('end',function(){
res.writeHead(200,{"Content-Type":"text/html"});
res.write("<form id=\"submitForm\" method=\"POST\">");
res.write("<textarea id=\"text\"rows=50 cols=50 >");
console.log(content);
if(content)
res.write(content.toString());
res.write("</textarea>");
res.write("<input type=\"submit\" value=\"submit\" />");
res.write("</form>");
res.write("<script>");
res.write("var windowLocation = location.href;");
res.write("document.getElementById(\"submitForm\").action=windowLocation + \'/data\';");
res.write("</script>");
res.end();
});
}else{
res.writeHead(200);
res.write("invalid/empty path name");
}
});
app.listen(8080);
and got this error -
Error: Most middleware (like json) is no longer bundled with Express and must be installed separately. Please see https://github.com/senchalabs/connect#middleware.
at Function.Object.defineProperty.get (/home/unknown/public_html/node/node_modules/express/lib/express.js:89:13)
I was using body parser before which i read in some solutions here and it gave me the same error middleware missing, i installed it globally then also got the same error and after that i read about json , so i installed it globally using
npm install -g json
did not work, then too. then i tried adding the dependancies -
{
"name": "express_shrib.js",
"version": "0.0.1",
"description": "Creating Shrib Using Express",
"main": "express_shrib.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "https://github.com/iamdeadman/nodejs.git"
},
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/iamdeadman/nodejs/issues"
},
"homepage": "https://github.com/iamdeadman/nodejs",
"dependencies": {
"express": ">= 1.2.0",
"json": ">= 9.0.0"
}
}
and ran npm install
still the same error -
Error: Most middleware (like json) is no longer bundled with Express and must be installed separately. Please see https://github.com/senchalabs/connect#middleware.
at Function.Object.defineProperty.get (/home/unknown/public_html/node/node_modules/express/lib/express.js:89:13)
Edit** - Code with the new body-parser module
var express = require('express');
var app = express();
var fs = require('fs');
var bodyParser = require('body-parser');
app.use(bodyParser());
app.post('/shrib/:file/:data',function(req,res){
var fileName = req.params.file;
var data = req.params.data;
req.on('data',function(data){ body+=data; } );
req.on('end' ,function(){
var postData = req.body;
var writeStream = fs.createWriteStream(fileName);
if(postData)
console.log(postData);
else{
console.log("failed miserably");
console.log(postData);
}
res.writeHead(200);
res.end();
});
});
app.get('/shrib/:file',function(req,res){
var fileName = req.params.file;
if(fileName != ''){
var readStream = fs.createReadStream(fileName);
var content;
readStream.on('data',function(chunk){
content+=chunk.toString();
console.log(content);
});
readStream.on('end',function(){
res.writeHead(200,{"Content-Type":"text/html"});
res.write("<form id=\"submitForm\" method=\"POST\">");
res.write("<textarea id=\"text\"rows=50 cols=50 >");
console.log(content);
if(content)
res.write(content.toString());
res.write("</textarea>");
res.write("<input type=\"submit\" value=\"submit\" />");
res.write("</form>");
res.write("<script>");
res.write("var windowLocation = location.href;");
res.write("document.getElementById(\"submitForm\").action=windowLocation + \'/data\';");
res.write("</script>");
res.end();
});
}else{
res.writeHead(200);
res.write("invalid/empty path name");
}
});
app.listen(8080);
and here i get
{}
in the console which means that the body object is empty for some reason.

With Express 4, the body parsing middleware (like other previously built-in middleware) was extracted out into the 'body-parser' module. However, this new module only handles JSON and urlencoded form submissions, not multipart.
If you need multipart support, you'd need to use something like connect-busboy or multer or connect-multiparty (connect-multiparty is essentially the old Express bodyParser middleware).
EDIT: Also, the name attribute is missing for the textarea input field. This is required, otherwise the field will not be sent with the form.

When using express 4 use body-parser middleware to get parameters.
Multipart has issue that it creates loads of temp files. So its better to avoid it whenever possible and use upload services directly.
app.use(function (req, res, next) {
var urlParser = require('url');
var url = urlParser.parse(req.url, true);
if (url.pathname == "/rest/file/upload") {
next();
} else {
var contentType = req.header("content-type");
if (contentType && contentType.indexOf("application/json") != -1) {
bodyParser.json({limit: 1024 * 1024 * 10})(req, res, next);
} else {
bodyParser.urlencoded({ extended: true, limit: 1024 * 1024 * 10})(req, res, next);
}
}
});
then just get your request parameter as :
console.log(req.param("parameter-name"));

Related

requested URL was not found on this server using javascript

When getting URL via firebase deploy --only hosting and use it, it work well and open the website, but when try put api/send like this Url: https://*******.web.app/api/send give me this error **
The requested URL was not found on this server.
and i try post url in postman and it show that error
**JavaScript code **
const functions = require('firebase-functions');
var {google} = require('googleapis');
var MESSAGING_SCOPE = "https://www.googleapis.com/auth/firebase.messaging";
var SCOPES = [MESSAGING_SCOPE];
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var router = express.Router();
var request = require('request');
app.use(bodyParser.urlencoded({extended:true}));
app.use(bodyParser.json());
router.post('/send', function(req, res){
getAccessToken().then(function(access_token){
var title = req.body.title;
var body = req.body.body;
var token = req.body.token;
request.post({
headers:{
Authorization: 'Bearer '+access_token
},
url: "https://fcm.googleapis.com/v1/projects/el-ma3sra/messages:send",
body: JSON.stringify(
{
"message":{
"token" : token,
"notification" : {
"body" : body,
"title" : title,
}
}
}
)
}, function(error, response, body){
res.end(body);
console.log(body);
});
});
});
app.use('/api', router);
function getAccessToken(){
return new Promise(function(resolve, reject){
var key = require("./service-account.json");
var jwtClient = new google.auth.JWT(
key.client_email,
null,
key.private_key,
SCOPES,
null
);
jwtClient.authorize(function(err, tokens){
if(err){
reject(err);
return;
}
resolve(tokens.access_token);
});
});
}
exports.api = functions.https.onRequest(app);
firebase.json
{
"hosting": {
"public": "public",
"rewrites":[
{
"source":"/api/send",
"function":"api"
}
],
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
]
}
}
i want solve my error
I think you configured the following API url
https://*******.web.app/api/api/send
The first api comes from your export (exports.api = ...) the second api comes from your express application where you assigned your router to start at api (app.use('/api'...)
So maybe try to assign your router at root path
app.use('/', ... )

How to solve "Cannot read property 'title' of undefined"?

I am using Postman to learn about APIs. The contents of my server.js file is in the code below. However, when I send a post through Postman, the error "Cannot read property 'title' of undefined" keeps showing.
var Product = require("./model/product");
var WishList = require("./model/wishlist");
app.post("/product", function (request, response) {
var product = new Product();
product.title = request.body.title;
product.price = request.body.price;
product.save(function (err, savedProduct) {
if (err) {
response.status(500).send({ error: "Could not save product" });
} else {
response.status(200).send(savedProduct);
}
});
});
app.use(express.json());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.listen(3000, function () {
console.log("Swag Shop API runing on port 3000...");
});
The product.js file contains the code below.
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var product = new Schema({
title: String,
price: Number,
likes: { type: Number, default: 0 },
});
module.exports = mongoose.model("Product", product);
I tried to send the following json file through Postman but then the errorType: "Cannot read property 'title' of undefined " was showing.
{
"title": "Test Title",
"price": 100.00
}
These are the folders to see the location of my files: Folders.
This solution using npm install express#">=3.0.0 <4.0.0" --save did not work in my case. After I used it in my terminal, the same error kept showing.
How can I solve this issue?
Try this and either use express.json() or bodyParser.json()
if you go into the file node_module/express/lib/express.js you can see under module dependencies body-parser module is already imported var bodyParser = require('body-parser);
var Product = require("./model/product");
var WishList = require("./model/wishlist");
//app.use(express.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.post("/product", function (request, response) {
var product = new Product();
product.title = request.body.title;
product.price = request.body.price;
product.save(function (err, savedProduct) {
if (err) {
response.status(500).send({ error: "Could not save product" });
} else {
response.status(200).send(savedProduct);
}
});
});
app.listen(3000, function () {
console.log("Swag Shop API runing on port 3000...");
});
Install express.js & mongoose by typing $npm install --save
express mongoose
Type the codes below on TOP for your proper
imports and declarations
var express = require('express');
var app = express();
var mongoose = require('mongoose');
var db = mongoose.connect('mongodb://localhost/swag-shop');

Heroku - specific route works locally but not on production

I have a node project which was deployed to an Heroku app.
The deploy was successful and i can open the app , but there is one route to which i'm getting a "Cannot GET" error (404) while other routes on the same page are working as expected.
Locally everything is working as expected and when i run heroku local in cmd i can see the response coming back from that function but i can't say the same for trying it from heroku app link.
server.js
'use strict';
var http = require ('http');
var url = require('url') ;
var express= require('express');
var app= express();
var port = process.env.PORT || 3000;
var mongoose = require ('mongoose');
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
mongoose.connect (db_details);
var conn=mongoose.connection;
var trip = require ('./Schemas/trip');
var user = require ('./Schemas/user');
app.all('/*', function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Content-Type,accept,access_token,X-Requested-With');
next();
});
conn.on('error', function(err) {
console.log('connection error: ' + err);
process.exit(1);
});
conn.once('open',function() {
console.log('connected successfuly to the remote DB');
app.use(require('./Routes')); //API routings
app.listen(port);
console.log("listening on port "+port+" and waiting for WS requests");
});
Routes/api/trip.js
'use strict'
var router = require('express').Router();
var mongoose = require('mongoose');
var trip = require ('../../Schemas/trip');
var user = require ('../../Schemas/user');
var Gmap = require ('../../TripBuilder/builder');
// get all trips
router.get('/getTrips', function(req, res) {
trip.find({},'trip_id Trip_Name Country City', function(err, trips) {
res.send(trips.reduce(function(userMap, item) {
userMap[item.id] = item;
return userMap;
}, {}));
});
});
// create new trip
router.post('/addNewTrip', function(req, res,next) {
let newTrip = new trip ({"Trip_Id":req.body.Trip_id,"Trip_Name":req.body.Trip_Name,"Trip_Date":req.body.Trip_Date,
"Trip_Owner":req.body.Trip_Owner,
"Country":req.body.Country,"City":req.body.City,"status":"Pending","Days":[],"Sites":[]});
return newTrip.save().then(function(){
return res.send("A Trip was created");
}).catch(next);
});
router.post('/addUserToTrip', async function(req, res,next) {
user.find({'email':req.body.email},'first_name last_name email', function(err,obj) {console.log("print " +obj); });
let secUser = {"Trip_Id":req.body.Trip_id};
});
router.post('/createRoute', function(req, res,next) {
var map=new Gmap();
var origins = ['Big Ben, London, UK','Bridge St, Westminster, London SW1A 2JR, UK','Palace of Westminster, Westminster, London SW1A 0PW, UK','Whitehall, Westminster, London SW1A 2ET, UK'];
var destinations =['Big Ben, London, UK','Bridge St, Westminster, London SW1A 2JR, UK','Palace of Westminster, Westminster, London SW1A 0PW, UK','Whitehall, Westminster, London SW1A 2ET, UK'];
map.calcRoute(origins,destinations).then(function(result){
map.longestroute=result; //save start and end
origins.splice(origins.indexOf( map.longestroute.origin), 1);
origins.splice(origins.indexOf( map.longestroute.destination), 1);
map.waypoints=origins;
map.setRoute(map.longestroute.origin,map.longestroute.destination,map.waypoints).then(function(route){
return res.send(route);
});
}).catch(next);
});
module.exports = router;
Calling https://APP-NAME.herokuapp.com/api/trip/createRoute returns "Cannot GET /api/trip/createRoute", while calling https://APP-NAME.herokuapp.com/api/trip/getTrips returns a response.
Heroku logs seems to record the request without any special exceptions but nothing is coming back.
I added "res.send("ok");" inside "createRoute" just to see at least that will be sent back but nothing.
Package.json
"name": "tripin",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node server.js"
},
"engines": {
"node": "9.8.0"
},
"author": "",
"license": "ISC",
"dependencies": {
"#google/maps": "^0.4.6",
"body-parser": "^1.18.2",
"express": "^4.16.2",
"http": "0.0.0",
"https": "^1.0.0",
"inspect-process": "^0.5.0",
"mongoose": "^5.0.9",
"node-dev": "^3.1.3",
"package.json": "^2.0.1",
"request": "^2.85.0"
}
}
Thanks
Edit:
router.post('/createRoute) and router.get('/createRoute) were attempted.
didn't work in either case
Your error messages is complaining about the GET, so it wants to GET "createRoute".
The create route path is a POST (so your HTTP request should be a POST).
You can check this by implementing a GET, and give a response your will reconize..
router.get('/createRoute', function(req, res) {
// .. your reconizalbe response here ..
res.send("Oops I did a GET, but wanted to POST");
}
and/or test with tool which can invoke the POST, like Postman or some other tool.
Ok , so as we all know programming rules state that the smaller the issue is, the harder it is to find it.
I managed to find out the solution:
I had my project duplicated in heroku - once in the root folder and once in its folder like it should be.
That threw off any routing i tried.
cleaning up heroku and re-deploy did the trick.
Thank you all for trying to help

NodeJS multi site web scrape

I am learning NodeJS and trying to scrape a fan wikia to get names of characters and store them in a json file. I have an array of character names and I want to loop through them and scrape each character name from each url in the array. The issue I am running into is:
throw new Error('Can\'t set headers after they are sent.');
Here is my source code at the moment:
var express = require('express');
var fs = require('fs');
var request = require('request');
var cheerio = require('cheerio');
var app = express();
app.get('/', function(req, res){
var bosses = ["Boss1","Boss2"];
for (boss in bosses) {
url = 'http://wikiasiteexample.com/' + bosses[boss];
request(url, function (error, response, html) {
if (!error) {
var $ = cheerio.load(html);
var title;
var json = { title: "" };
$('.page-header__title').filter(function () {
var data = $(this);
title = data.text();
json.title = title;
})
}
fs.writeFile('output.json', JSON.stringify(json, null, 4), {'flag':'a'}, function(err) {
if (err) {
return console.error(err);
}
});
res.send('Check your console!')
})
}
})
app.listen('8081')
console.log('Running on port 8081');
exports = module.exports = app;
You're calling res.send() for every request you make.
Your HTTP request can only have one response, so that gives an error.
You must call res.send() exactly once.
Promises (and Promise.all()) will help you do that.

Get body json specific data in node

I use the req res for node js from the following module and I want to send in post message body the following json
{
"Actions": [
{
"file1": {
"name": "file 1",
"content": "file 2 content"
},
"file2": {
"name": "file 2",
"content": "file 2 content"
}
}
]
}
How can I get from the req body the name and the content
I use the create server and there I've req and res
https://github.com/nodejitsu/node-http-proxy
UPDATE
this is my code
var http = require('http'),
httpProxy = require('http-proxy'),
url = require('url');
http.createServer(function (req, res) {
var hostname = req.headers.host.split(":")[0];
console.log(req.body);
The problem is that Node's http API is awful. To get the body, you need to listen for data events and build the body string yourself.
var http = require('http'),
url = require('url');
var server = http.createServer(function (req, res) {
var body = '';
req.on('data', function (chunk) {
body += chunk;
});
req.on('end', function () {
var json = JSON.parse(body);
console.log(json.Actions[0].file1.content);
res.writeHead(200);
res.end();
});
});
server.listen(8080);
I highly recommend using something like Express that hides all these details.

Categories