Getting connect ECONNREFUSED 127.0.0.1:80 when attempting HTTP request - node.js

I am attempting to make a http request to news.google.com using the native node.js http module. I am getting the connect ECONNREFUSED 127.0.0.1:80 error when I tried the following
var http = require('http');
var payload = JSON.stringify({
name: 'John Smith',
email: 'john.smith#smith.com',
resume: 'https://drive.google.com/open?id=asgsaegsehsehseh'
});
var options = {
hostname: 'https://news.google.com',
path: '/',
method: 'GET'
};
var httpRequest = http.request(options, function(request, response) {
console.log('STATUS', response.statusCode);
response.setEncoding('utf8');
response.on('data', function(chunk) {
console.log('BODY:', chunk);
});
response.on('end', function() {
console.log('No more data in response');
});
});
httpRequest.on('error', function(e) {
console.log('Error with the request:', e.message);
});
httpRequest.write(payload);
httpRequest.end();
Why am I getting this error?
I tried using the request npm module. And it worked!

In my case, issue was actually default behaviour of HTTP client that I was using, axios.
By default, axios redirects us to 127.0.0.1:80 if it doesn't find requested URL or http method(GET/POST/PUT). So better check your URL if are also using axios.

My problem was while using supertest and jest. My mistake was not putting "/" as a prefix to some url. So, double check if the url for the request you are making is proper.

I'm using axios and this error occurred with get request, solved it by adding http:// before my URL (in my case the server is http)

There are several issues here:
The hostname field of the options structure should be just the host, not a URL. In your case it should just be 'news.google.com'.
The signature for the callback to the request method is function (response) -- yours is function (request, response). Lose the first parameter.
As written this will aways return an HTTP redirection to the https site. Replace var http = require('http'); with var https = require('https'); and then use https everywhere instead of http.

I encountered this issue while using supertest and jest. I made the mistake of using ./users instead of /users as the url.

I had the same problem with jest and supertest. Just changed api/blogs to /api/blogs and it worked !

I had the same problem.
Solve it by fixing the HTTP request path mistake in my code.

I had this problem, and my solution (That might not be the same for most people) was that the server was not listening yet, I had to call the axios function after.

store the root url in some variable or environtment and append it before request
so instead of
axios.get('/api/myurl')
do something like
let baseUrl = 'https://google.com"
axios.get(baseUrl + '/api/myurl')

Another cause for this error could be that in your code, you might be referring to an environment variable as:
const localhostUrl = process.env.LOCALHOST_URL;
Whilst, not having this variable defined, (as expected), in your .env file as:
LOCALHOST_URL = http://localhost:8000/

Related

Send a GET-request after app starts listening

I know this is unorthodox, but I was wondering if there's a way to use a redirect inside of the app.listen, something like this:
app.listen(app.get('port'), function () {
//res.redirect("some url")
})
The fact is I need to launch a GET request after the app is on listen mode, after some research I've found it could be done with a redirect; clearly, I don't have a routing and a response object res to afford it.
How could I achieve this?
You can simply run an http request in you ready hanlder function.
For instance you could use the request package:
const request = require('request');
app.listen(app.get('port'), function () {
request('http://your.url', function (error, response, body) {
// do something with the response
});
})
Of coure you'll need to npm i request in order for the above example to work and you can choose whatever http client you prefer and replace it.

Capturing GET request params in Node.js

I am trying to capture current GET URL and query params in node.js code. I jut realized windows.loication does not work in node.js as it is for client-based execution only. I have tried multiple things but am not able to capture the GET request. Here is what all I have tried.
var url = require('url');
var url_parts = url.parse(request.url, true);
var query = url_parts.query;
var request = require('request');
var query = url.parse(request.url,true).query;
getFormattedUrl(req);
function getFormattedUrl(req) {
console.log("req.url: " + req.url);
return url.format({
protocol: req.protocol,
host: req.get('host')
});
}
All of these fail for me, giving the errors like :
2016-12-17T03:32:36.164600+00:00 app[web.1]: ReferenceError: request is not defined
2016-12-17T03:43:46.569603+00:00 app[web.1]: ReferenceError: request is not defined
2016-12-17T03:45:14.509168+00:00 app[web.1]: TypeError: Parameter 'url' must be a string, not undefined
Can someone pls suggest how to cpature the GET params in node.js.
If you are using express 4.x then you want req.query
If you are trying to capture the request that is being made from a NODE JS server to another http/https endpoint for debugging or viewing purposes, this might help
var options2 = {
url: "https://www.google.com",
port: '443',
method: 'GET'
}
request(options2, function(error, response){
console.log(options2);
});
where options2 is the defined URL the node js server is trying to reach
When you console log options2 (a variable name i've used, you can call it anything), it will give you all the information about the HTTPS/HTTP call the server is making.
Sample Express JS 4 Code
var express = require('express')
var app = express()
app.get('/', function (req, res) {
res.send('Someting')
console.log(req.query);
})
app.listen(3000, function () {
console.log('Example app listening on port 3000!')
})
This will launch a localhost server on port 3000
If you do localhost:3000?q=test you will see
{q: test}
in the console/log.
To fix the problem above, just install request module from the command line first, before using it:
npm install request
Interesting things is that to achieve what you need, you do not need to use request module at all. Just use url module as you did above, pass request object (not a module, but actual calling request), and format it using url.format
const url = require('url')
function getFormattedUrl(req) { return url.format(req.url) }

Cross-domain POST request in Node.JS with preflight?

I have just started with Node.
I am trying to get cross-domain form data from an HTML form to parse in a Node.js server. I have been able to do this with simple POST data, not with POST requests that require preflight.
I am running the Node code on cloud9 app servers. I am also using the Cors module to handle the requests. This module works well with simple requests (test here to see a simple request work), however with requests that require preflight I get this result from the Chrome inspector console.
XMLHttpRequest cannot load https://nms-motaheri-1.c9.io:8080/mail.
The request was redirected to 'https://c9.io:8080/api/nc/auth?.....SHORTENED',
which is disallowed for cross-origin requests that require preflight.
Here is my server.js code:
// Define dependencies
var express = require('express')
, cors = require('cors')
, app = express()
, parse_post = require("parse-post");
// Core module config
var corsOptions = {
origin: '*',
preflightContinue: true // <- I am assuming this is correct
};
app.use(cors(corsOptions));
// Respond to option request with HTTP 200
// ?? Why is this not answering my OPTION requests sufficiently ??
app.options('*',function(req,res){
res.send(200);
});
// Give a hello world response to all GET requests
app.get('/',function(req,res){
res.sendFile(__dirname + '/index.html');
});
// Handle all POST requests to /mail
app.post('/mail', parse_post(function(req, res) {
console.log(req.body);
res.json({msg: 'This is CORS-enabled for all origins!'});
})
);
// Listen on default Cloud9 port which is 8080 in this case
app.listen(process.env.PORT, function(){
console.log('CORS-enabled web server listening on port ' + process.env.PORT);
});
Why is this happening and how can I satisfactorily answer the OPTION request for my POST with pre-flight?
Here is the post request and response in Chrome dev tools:
Turns out that part of the problem was that the cloud9 server was set to private making these requests all redirect.
After making the server public, the redirections stopped. However, I received an error that the Node.js server did not have any Access-Control-Allow-Origin headers to allow requests from my cross origin domain. I noticed that "simple" with-out preflight requests would go through. So instead of trying to understand why it was not accepting my allow-all-origin-configuration on the Node.js side I decided to serialized the POST data to get rid of the preflight requirement and changed the data type in my angular request to plain text.
To get rid of preflight, first get rid of any POST header configuration (cache, etc), make sure your request Content-Type is plain text and make sure your actual content is plain text too. So if it is in JSON serialize it in jQuery before sending it with POST.
This is what my new Angular Post request code looked like:
sendEmail: function(email) {
var config = {
headers: {
'Content-Type': 'text/plain'
}
};
var POSTDATA= JSON.stringify(POSTDATAJSON);
return $http.post(POSTURL, POSTDATA, config)
}
And in Node.js this, I am using the cors Node.js module:
app.post('/mail', parse_post(function(req, res) {
var postReq = JSON.parse(Object.keys(req.body));
}));

Ajax request from another domain using AngularJs

I'm using this book to learn AngularJS where I build this webapp with Angular, Node, Deployd. Now, my app stays at localhost:5000/app.html, 5000 is the port where node web server listen. I try to retrieve my data stored with deployd in this way:
$http.get("localhost:5500/products")
.success(function (data) {
$scope.data.products = data;
})
.error(function (error) {
$scope.data.error = error;
});
But this cause an error: no 'Access-Control-Allow-Origin' header is present on the requested resource. How can I solve this? Thanks :)
Kevin B is right. It's the Same Origin Policy blocking your request.
What you should do here is to direct your requests from the client to your node server ("/products"). Here, you can easily proxy them to localhost:5500, e.g. using node-http-proxy (https://github.com/nodejitsu/node-http-proxy).
From the node-http-proxy README.md (adapted the host/port to your use-case):
var httpProxy = require('http-proxy');
var proxy = httpProxy.createProxyServer(options);
require('http').createServer(function(req, res) {
proxy.web(req, res, { target: 'http://localhost:5500' });
});
It might be, that this interferes with your current node server (serving you the client-side angular code in the first place). In case you're using Express for this, you can combine "http" and "http-proxy" like this: https://stackoverflow.com/a/22244101/3651406

Return data from node js to $.ajax

From one of the machines in my network (client), I am making $.ajax() request to my Nodejs server like,
//Client : index.html
$.ajax({
type:"post",
url:'http://192.168.2.6:8080',
data:JSON.stringify({"loginData":{"uanme":"maverick","upass":"asd"}}),
success:function(data){console.log(data);alert(data);},
error:function(){alert('Error aala');}
});
AND my Nodejs server is
//listener.js
var server = require('http').createServer(function (request, response) {
var body='';
if(request.method=='POST'){
request.on('data',function(data){
body+=data;
});
request.on('end',function(){
console.log(body);
});
}
}).listen(8080);
These console.log()s are working absolutely fine. I get the exact same data I am sending on the node side,
Now my question is, in php when we make an $.ajax() request, we use echo in our php file to send the data back to the client,
What should I have to do on server side in Nodejs (listener.js file) if I want to send the data back to the client?
var server = require('http').createServer(function (request, response) {
var body='';
if(request.method=='POST'){
request.on('data',function(data){
body+=data;
});
request.on('end',function(){
console.log(body);
//response.setHeader("Content-Type", ""); set the header to your content type
response.write('foo'); // <-----
response.end('Dear client, I have cake for you'); // <-----
});
}
}).listen(8080);
Further reading Node.js Documentation
Solved this problem myself.
The problem was with cross domain ajax requests.
I don't know why this was happening, even though I had specified url:localhost:8080 in my $.ajax call...
Solved the problem my adding
response.setHeader("Access-Control-Allow-Origin", "*");
in my response headers.
PEACE

Resources