Issue calling a https REST service in Node - javascript

I am trying to call an internally hosted REST webservice from Node.js but I am getting "problem with request: unable to verify the first certificate"
The web service is https there is no http version
There is my code
var https = require('https');
const fs = require('fs');
var options = {
host: 'path.to.application.rest.service',
port: 443,
path: '/Function',
method: 'GET',
cert: fs.readFileSync('<Path to Cert>')
};
var req = https.request(options, function(res) {
console.log('STATUS: ' + res.statusCode);
console.log('HEADERS: ' + JSON.stringify(res.headers));
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log('BODY: ' + chunk);
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
req.end();
This is the certificate chain of the service
I have tried using all the different certs in the chain as the one in the options but they all fail with the same error. What am I doing wrong/missing?

Related

Getting no data with express/react/next.js data request using http

Problem:
I am trying to request data from http://localhost:3000/auth/sendUserData using http, but I am getting no data/response (no console.logs).
What I'm using:
Next.js/React, Node (backend server), getInitialProps (Next.js).
Code:
Userdata.js
const http = require("http");
const Userdata = {};
Userdata.getUserData = async function(){
let url = `http://${process.env.HOST}:${process.env.PORT}/auth/sendUserData`
console.log(url);
const options = {
host: process.env.HOST,
port: process.env.PORT,
path: '/auth/sendUserData'
};
http.get(options, function(res) {
console.log("Got response: " + res.statusCode);
res.on("data", function(chunk) {
console.log("BODY: " + chunk);
});
}).on('error', function(e) {
console.log("Got error: " + e.message);
});
};
export default Userdata;
http://localhost:3000/auth/sendUserData
{
_id: "5c5521f823a5d183945fd62f",
name: "Saddy",
steamID: "76561198151478478",
__v: 0
}
Problem was with backend authentication since it was rendered on the server and not on the client, causing the session to be lost

Http GET Request from NodeJS to external API with http.get()

I am trying to do an HTTP GET request to an external API with NodeJS (using Express), but I am not getting any data back. My code is the nextone:
import * as http from "http";
const options = {
host: "EXAMPLE.COM",
path: "/MY/PATH",
headers: {
"Content-Type": "application/json",
"Authorization": "Basic XXXXXXXXXXXXXXXXXX"
}
};
const req = http.get(options, function(res) {
console.log("statusCode: " + res.statusCode);
res.on("data", function (chunk) {
console.log("BODY: " + chunk);
});
});
But the response I get is:
statusCode : 302 and BODY is empty.
The external API works properly (I have tried doing a http GET Request with INSOMNIA and returns data)
The request I am doing NEEDS an Authorization Token
What am I doing wrong? or what can I do to get the data back?
Cheers
You are just throwing data to console.log and not responding to request.
You did not mention if what http server you are using with node. In case you are using express.js (most common one) you should have something like:
const express = require("express");
const app = express();
const port = 3003;
const http = require("http");
// your webserver url localhost:3003/fetch-something
app.get("/fetch-something", (req, res) => {
const options = {
host: "EXAMPLE.COM",
path: "/MY/PATH",
headers: {
"Content-Type": "application/json",
Authorization: "Basic XXXXXXXXXXXXXXXXXX"
}
};
const httpReq = http.get(options, function(httpRes) {
//output status code to your console
console.log("statusCode: " + httpRes.statusCode);
httpRes.on("data", function(chunk) {
// still nothing happens on client - this will also just print to server console
console.log("data", chunk);
// return some data for requested route
return res.send(chunk);
});
});
});
app.listen(port, () => console.log(`Example app listening on port ${port}!`));

communicate between a server and a client with node.js

I have a node.js Server:-
// *********** Server that receives orders ************ //
// to use features of the http protocol. //
var http = require('http');
// initialize to empty string. //
var req = "";
// create the server that will receive an order Request. //
var server = http.createServer(function(req,res) {
res.writeHead(200, {'content-type': 'text/plain'});
// when data is successfully received, a success message is displayed. //
res.on('data', function(data){
req += data; // received data is appended. //
console.log("We have received your request successfully.");
});
});
// An error message is displayed - error event. //
server.on('error', function(e){
console.log("There is a problem with the request:\n" + e.message);
});
// server listens at the following port and localhost (IP). //
server.listen(8000, '127.0.0.1');
and then I have a node.js Client:-
var http = require("http");
var querystring = require("querystring");
var postOrder = querystring.stringify({
'msg': 'Hello World!'
});
var options = {
hostname: '127.0.0.1',
port: 8000,
path:'/order',
method:'POST',
headers:{
'Content-Type' :'application/x-www-form-urlencoded',
'Content-Length' : postOrder.length
}
};
var req = http.request(options, function(res) {
console.log('STATUS: ' + res.statusCode);
console.log('HEADERS: ' + JSON.stringify(res.headers));
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log('BODY: ' + chunk);
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
// write data to request body
req.write(postOrder);
req.end();
I am trying to figure out how I can make the client post its order to the server and get a response back from the server...either a success message or an error message...using command line.
currently I run the server on cmd line $ node server.js
and then a run the client $ node client.js
but i get no responses.
I think that have problems from the server:
The Server must be:
http.createServer(function(req, res) {
if (req.method == 'GET') {
} else if (req.method == 'POST') {
var body = '';
req.on('data', function(data) {
body += data;
});
req.on('end', function() {
console.log("We have received your request successfully.");
});
}
res.end("ok");
})

Steps to send a https request to a rest service in Node js

What are the steps to send a https request in node js to a rest service?
I have an api exposed like (Original link not working...)
How to pass the request and what are the options I need to give for this API like
host, port, path and method?
just use the core https module with the https.request function. Example for a POST request (GET would be similar):
var https = require('https');
var options = {
host: 'www.google.com',
port: 443,
path: '/upload',
method: 'POST'
};
var req = https.request(options, function(res) {
console.log('STATUS: ' + res.statusCode);
console.log('HEADERS: ' + JSON.stringify(res.headers));
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log('BODY: ' + chunk);
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
// write data to request body
req.write('data\n');
req.write('data\n');
req.end();
The easiest way is to use the request module.
request('https://example.com/url?a=b', function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body);
}
});
Note if you are using https.request do not directly use the body from res.on('data',... This will fail if you have a large data coming in chunks. So you need to concatenate all the data and then process the response in res.on('end'. Example -
var options = {
hostname: "www.google.com",
port: 443,
path: "/upload",
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(post_data)
}
};
//change to http for local testing
var req = https.request(options, function (res) {
res.setEncoding('utf8');
var body = '';
res.on('data', function (chunk) {
body = body + chunk;
});
res.on('end',function(){
console.log("Body :" + body);
if (res.statusCode !== 200) {
callback("Api call failed with response code " + res.statusCode);
} else {
callback(null);
}
});
});
req.on('error', function (e) {
console.log("Error : " + e.message);
callback(e);
});
// write data to request body
req.write(post_data);
req.end();
Using the request module solved the issue.
// Include the request library for Node.js
var request = require('request');
// Basic Authentication credentials
var username = "vinod";
var password = "12345";
var authenticationHeader = "Basic " + new Buffer(username + ":" + password).toString("base64");
request(
{
url : "https://133-70-97-54-43.sample.com/feedSample/Query_Status_View/Query_Status/Output1?STATUS=Joined%20school",
headers : { "Authorization" : authenticationHeader }
},
function (error, response, body) {
console.log(body); } );
Since there isn't any example with a ´GET´ method here is one.
The catch is that the path in the options Object should be set to '/' in order to send the request correctly
const https = require('https')
const options = {
hostname: 'www.google.com',
port: 443,
path: '/',
method: 'GET',
headers: {
'Accept': 'plain/html',
'Accept-Encoding': '*',
}
}
const req = https.request(options, res => {
console.log(`statusCode: ${res.statusCode}`);
console.log('headers:', res.headers);
res.on('data', d => {
process.stdout.write(d)
})
})
req.on('error', error => {
console.error(`Error on Get Request --> ${error}`)
})
req.end()
The example using 'GET' method is good but it can also be used with constant variables in TypeScript/Node.js setup. If that's the case, the functions on('error') and end() have to be defined outside of the https.request function.
const https = require('https')
const options = {
hostname: 'www.google.com',
port: 443,
path: '/',
method: 'GET',
headers: {
'Accept': 'plain/html',
'Accept-Encoding': '*',
}
}
const request = https.request(options, res => {
const callback = (data: string) => {
process.stdout.write(`response data: ${data}`);
}
res.on('data', callback)
})
request.on('error', error => {
console.error(`Error on Get Request --> ${error}`)
})
request.end()

Node.js Requests returning 301 redirects

I'm brand new to node.js, but I wanted to play around with some basic code and make a few requests. At the moment, I'm playing around with the OCW search (http://www.ocwsearch.com/), and I'm trying to make a few basic requests using their sample search request:
However, no matter what request I try to make (even if I just query google.com), it's returning me
<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/0.7.65</center>
</body>
</html>
I'm not too sure what's going on. I've looked up nginx, but most questions asked about it seemed to be asked by people who were setting up their own servers. I've tried using an https request instead, but that returns an error 'ENOTFOUND'.
My code below:
var http = require('http');
http.createServer(function (request, response) {
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('Hello World\n');
var options = {
host:'ocwsearch.com',
path:
'/api/v1/search.json?q=statistics&contact=http%3a%2f%2fwww.ocwsearch.com%2fabout/',
method: 'GET'
}
var req = http.request(options, function(res) {
console.log("statusCode: ", res.statusCode);
console.log("headers: ", res.headers);
res.on('data', function(d) {
process.stdout.write(d);
});
});
req.end();
req.on('error', function(e) {
console.error(e);
});
}).listen(8124);
console.log('Server running at http://127.0.0.1:8124/');
Sorry if this is a really simple question, and thanks for any help you can give!
For me the website I was trying to GET was redirecting me to the secure protocol. So I changed
require('http');
to
require('https');
The problem is that Node.JS's HTTP Request module isn't following the redirect you are given.
See this question for more: How do you follow an HTTP Redirect in Node.js?
Basically, you can either look through the headers and handle the redirect yourself, or use one of the handful of modules for this. I've used the "request" library, and have had good luck with it myself. https://github.com/mikeal/request
var http = require('http');
var find_link = function(link, callback){
var root ='';
var f = function(link){
http.get(link, function(res) {
if (res.statusCode == 301) {
f(res.headers.location);
} else {
callback(link);
}
});
}
f(link, function(t){i(t,'*')});
}
find_link('http://somelink.com/mJLsASAK',function(link){
console.log(link);
});
function i(data){
console.log( require('util').inspect(data,{depth:null,colors:true}) )
}
This question is old now, but I got the same 301 error and these answers didn't actually help me to solve the problem.
I wrote the same code:
var options = {
hostname: 'google.com',
port: 80,
path: '/',
method: 'GET',
headers: {
'Content-Type': 'text/plain',
}
};
var http = require('http');
var req = http.request(options, function(res) {
console.log('STATUS:',res.statusCode);
console.log('HEADERS: ', JSON.stringify(res.headers));
res.setEncoding('utf8');
res.on('data', function(chunk) {
console.log(chunk);
});
res.on('end', function() {
console.log('No more data in response.');
});
});
req.on('error', function(e) {
console.log('problem with request: ', e.message);
});
console.log(req);
req.end();
so after some time I realized that there's a really tiny mistake in this code which is hostname part:
var options = {
hostname: 'google.com',
...
you have to add "www." before your URL to get html content, otherwise there would be 301 error.
var options = {
hostname: 'www.google.com',

Categories