Parsing Get HTTP Request for parameters and using in http response - node.js

I am trying to learn node.js. Here is the basic hello World example where I expect a http request like
http://localhost:3000?fname=ABC&lname=XYZ
And return response to print on the browser
Hello, ABC XYZ!
This is working fine. But if you see the response.end function I have something like query.lname || "Anonymous". I was expecting that in case the lname is not specified in the URL then the response contains 'Anonymous' in place of last name. But this doesn't happen and I get
Hello, ABC undefined!
The code is as follows. Kindly help me understand this. Thanks for the help.
var http = require('http');
var url = require('url');
var querystring = require('querystring');
http.createServer(function(request, response) {
var query = querystring.parse(url.parse(request.url).query || "");
response.writeHead(200,{’content-type’:"text/plain"});
response.end("Hello, "+(query.fname+" "+ query.lname || "Anonymous")+"!\n");
}).listen(3000);

Related

Redirect to a https url on server rather than sending 3XX in express

I have a sample http server .
I have a post API which in some scenario have to route to a third party https-server.
Third party server also exposes a post API.
I dont want to send a redirect to client and do this silently on http server.
My application is built using express.
I have tried using request module and tried to use pipe like this .. but request is timing out.
let request = require('request');
console.log(`vishal going here for 300 `);
var pipe = req.pipe(request.post('https url here'));
var response = [];
pipe.on('data', function (chunk) {
response.push(chunk);
});
pipe.on('end', function () {
var res2 = Buffer.concat(response);
console.log(res2);
res.send(res2);
});
Not sure whats missing.
Also how to pass the body and hears to https server request

JSONSerialization makes incorrect JSON object. Swift

I'm creating an iOS app that connects to a NodeJS server. The get method works fine but the POST method has problems.
var urlRequest = URLRequest(url: "http://localhost:3000/register")
urlRequest.httpMethod = "POST"
let info: [String:Any] = ["username": "username", "password":"username", "email":"username#username.com"]
do {
let jsonInfo = try
JSONSerialization.data(withJSONObject: info, options[])
urlRequest.httpBody = jsonInfo
} catch {
print("ERROR")
return
}
The request gets sent but something goes wrong with JSONSerialization because this is the JSON data that the server gets:
{'{"email":"username#username.com","username":"username","password":"username"}': '' }
This is what I'm going for:
{"email":"username#username.com","username":"username","password":"username"}
This is part of the server code:
const express = require('express');
const bodyParser = require('body-parser');
var app = express();
var allowMethods = function(req, res, next) {
res.header('Access-Control-Allow-Methods', 'GET, POST, PATCH, PUT, DELETE');
next();
}
http.createServer(app).listen(3001);
console.log("Server started");
app.use(bodyParser.urlencoded({extended: true}));
app.use(allowMethods);
const _ = require('lodash');
let b = _.pick(req.body, ['username', 'password', 'email']);
Any ideas on what I'm doing wrong? I'd like to avoid using alamofire if possible. I've tried changing the format of the dictionary but always turns out as:
{ 'the whole dictionary is the key': ''}
I've also tried using pretty print and this was the result:
{ '{\n "email" : "username#username.com",\n "username" : "username",\n "password" : "username"\n}': '' }
Any help is appreciated. Thank you!
EDIT:
I tried Mike Taverne's suggestions.
I changed the server code to use this instead:
app.use(bodyParser.json());
But I receive an empty body from the simulator.
I also added these to the swift code:
urlRequest.addValue("application/json", forHTTPHeaderField: "Content-Type")
urlRequest.addValue("application/json", forHTTPHeaderField: "Accept")
But the server also receives an empty body and by empty body I mean the data I'm trying to send is received as empty by the server. When I check the httpBody the data is there but for some reason the server doesn't receive it.
I believe your Swift code is fine. When I did this in a playground:
print(String(data: urlRequest.httpBody!, encoding: String.Encoding.utf8)!)
It printed:
{"username":"username","password":"username","email":"username#username.com"}
I'm not an expert on body-parser, but I think that instead of this:
bodyParser.urlencoded({extended: true})
You should be using this:
bodyParser.json([options]) //not sure which options exactly you need
You may need to set Content-Type: application/json header as well. Refer to the body-parser documentation for more info.
I solved it by changing the data itself. Instead of forcing it to pass JSON I passed it as a string encoded using UTF8
let dataString = "username=username&password=username&email=username#username.com"
urlRequest.httpBody = dataString.data(using: .utf8)
I got the answer by using the method in this post:
HTTP Request in Swift with POST method

Problem with scraping OP.GG website with node.js and cheerio

I'm a beginner with node.js and cheerio and a little help would be awesome :D
I try to scrape the pubg.op.gg website to have two simple elements to show them in the console.
Here is my code:
var url = "https://pubg.op.gg/user/K1uu"
var request = require('request');
var cheerio = require('cheerio');
var cheerioAdv = require('cheerio-advanced-selectors');
request(url, function(err, resp, body) {
var $ = cheerio.load(body);
var playerName = $('.player-summary__name');
var playerNameText = playerName.text();
console.log(playerNameText);
var playerRank = $('.ranked-stats__rating-point');
var playerRankText = playerRank.text();
console.log(playerRankText);
})
I try to have something like this : "Kyuu - 1503"
No problem for the Kyuu value for playernickname but impossible to have the 1503 however the name of the div is correct !
Where is my problem ?
Thanks guys !!
Hey and welcome to StackOverflow!
That website uses AJAX to fetch the ratings, so when the HTML is loaded the ratings are not available and the ranked-stats__rating-point class does not exist yet. If you check it with the browser's developer tools, you can see that it requests 3 additional URLs for the 3 different rating point (the only difference is the queue_size URL param).
https://pubg.op.gg/api/users/59fdce2bdf1b210001a9324d/ranked-stats?season=pc-2018-01&queue_size=1&mode=tpp
https://pubg.op.gg/api/users/59fdce2bdf1b210001a9324d/ranked-stats?season=pc-2018-01&queue_size=2&mode=tpp
https://pubg.op.gg/api/users/59fdce2bdf1b210001a9324d/ranked-stats?season=pc-2018-01&queue_size=4&mode=tpp
You should be able to request the first rating like this:
var url = "https://pubg.op.gg/api/users/59fdce2bdf1b210001a9324d/ranked-stats?season=pc-2018-01&queue_size=1&mode=tpp";
var request = require('request');
request(url, function(err, resp, body) {
var jsonData = JSON.parse(body);
var score = jsonData['stats']['rating'];
console.log(score); // outputs "1520"
} );
However the username is not available from these endpoints, so you need to find another API endpoint for that if you want to fetch these for arbitrary usernames.
Hi korsosa and thanks for your answer !
Yes, there is multiple elements with ranked-stats__rating-point for the name.
There is the result of your code :
var playerRankText = playerRank[1].text();
TypeError: Cannot read property 'text' of undefined

scraping data from a website node js

i am new to scraping data from a website, i would like to scrape the level number from: https://fortnitetracker.com/profile/pc/Twitch.BadGuyBen, i have tried using cheerio and request for this task and im not sure if im using the right selector maybe some tips on what i should do. this is my code:
var request = require('request');
var cheerio = require('cheerio');
var options = {
url: `https://fortnitetracker.com/profile/pc/Twitch.BadGuyBen`,
method: 'GET'
}
request(options, function (error, response, body) {
var $ = cheerio.load(body);
var level = "";
var xp = "";
$('.top-stats').filter(function(){
var data = $(this);
level = data.children().first().find('.value').text();
console.log(level);
})
});
again i am not sure if i have even selected the right class much appreciated.
EDIT:
also '.top-stats' is present further on
website open in chrome dev tools
other .top-stats class
You can't use request to get the body since the stats are displayed using javascript. You will have to use something like puppeteer to request the page and execute the javascript and then scrape the stats.

how to inspect requests response proxied through node.js

I am trying to use node.js to setup a simple proxy server. The idea behind that is to get all web services calls made to one web service go through a node.js proxy in order to easily inspect and debug web service calls.
In order to do that, I am trying to use the following code to proxy the requests:
var
url = require('url'),
http = require('http'),
acceptor = http.createServer().listen(8008);
acceptor.on('request', function(request, response) {
console.log('request ' + request.url);
request.pause();
var options = url.parse(request.url);
options.headers = request.headers;
options.method = request.method;
options.agent = false;
var connector = http.request(options, function(serverResponse) {
serverResponse.pause();
response.writeHeader(serverResponse.statusCode, serverResponse.headers);
serverResponse.pipe(response);
serverResponse.resume();
});
request.pipe(connector);
request.resume();
});
But I can't figure out where to inspect / dump to file the response. With node-inspector, I was looking at the response object at line: serverResponse.pipe(response); but the body of the response is not yet available.
I found the following question node.js proxied request body but it is written in CoffeeScript.
The idea is write your own 'data' handler and don't use pipe().
You cannot eavesdrop on the data once you piped the stream.

Resources