Check url-redirection using axios in nodejs - javascript

I'm using axios for API calling in nodejs.
I want to check if "https://origin.com/?url=https://destination.com" this url is redirecting to "destination.com".
So which status/headers I can check in axios response.
What will be the condition to check if it goes to "destination.com"
var express = require('express');
const axios = require('axios');
var app = express();
app.get('/test', function (req, res) {
// Check if it redirects
axios.get('https://origin.com/?url=https://destination.com')
.then(response => {
console.log(response);
// Here I want to check if it redirects successfully to "destination.com"
if (condition) {
// Successfully redirected to "destination.com"
}
})
.catch(error => {
console.log(error);
});
})
var server = app.listen(8081, function () {
var host = server.address().address
var port = server.address().port
console.log("Example app listening at http://%s:%s", host, port)
})

I think you should try to use https for api, then in the response header you can find that it direct to the "destination.com".
Https is much simple and easy to use.
const https = require('https');
https.get('https://encrypted.google.com/', (res) => {
console.log('statusCode:', res.statusCode);
console.log('headers:', res.headers);
res.on('data', (d) => {
process.stdout.write(d);
});
}).on('error', (e) => {
console.error(e);
});

You can find the redirect url under responseURL key,
get fetchedUrl by
const fetchedUrl = response.request.res.responseURL;
see this
Environment node: v8.9.4 axios: ^0.18.0

Related

Why my socketio is not connecting with my socketio-client?

i am working on a chatapp project that needs a real time chatting so i have used socketio in my server side which is written in nodejs and than used socketio-client in my main chatapp react-native project.
But now a problem is coming my socket is not initializing. I'm not able to connect my server with my main app. I am using socketio and socketio client my both the socket version are same 4.5.1 but it's not even connecting. I have tried to use old version of socket but its also not working and I have also tried to change my localhost port to 4000 but it's also not working.
My server code:
const express = require('express');
var bodyParser = require('body-parser');
const app = express();
const http = require('http');
const server = http.createServer(app);
const { Server } = require("socket.io");
const io = new Server(server);
const port = process.env.PORT || 3000;
require('./src/config/database')
const user_routes = require('./src/user/users.routes');
app.use(bodyParser.urlencoded({extended: true}))
app.use(express.json())
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
app.use('/User', user_routes)
io.on('connection', (socket) => {
console.log('a user connected');
socket.on('send_message',(data)=>{
console.log("received message in server side",data)
io.emit('received_message',data)
})
socket.on('disconnect', () => {
console.log('user disconnected');
});
});
server.listen(port, () => {
console.log( `Server running at http://localhost:${port}/`);
});
My app socketservice file code:
import io from 'socket.io-client';
const SOCKET_URL = 'http://localhost:3000'
class WSService {
initializeSocket = async () => {
try {
this.socket = io(SOCKET_URL, {
transports: ['websocket']
})
console.log("initializing socket", this.socket)
this.socket.on('connect', (data) => {
console.log("=== socket connected ====")
})
this.socket.on('disconnect', (data) => {
console.log("=== socket disconnected ====")
})
this.socket.on('error', (data) => {
console.log("socekt error", data)
})
} catch (error) {
console.log("scoket is not inialized", error)
}
}
emit(event, data = {}) {
this.socket.emit(event, data)
}
on(event, cb) {
this.socket.on(event, cb)
}
removeListener(listenerName) {
this.socket.removeListener(listenerName)
}
}
const socketServcies = new WSService()
export default socketServcies
Where I have marked it should be connected = true but it's false in the dev console I have done console log so check that it's connecting or not and I can see that it's not connecting. How to make it connect?
There is no error in my app or server I have checked many times and my server is also running when I am running my app.
Answering my own question
The problem was i was using android emulator and android in an emulator can't connect to localhost you need to use the proxy ip so when i add http://10.0.2.2:3000 in const SOCKET_URL = 'http://10.0.2.2:3000' than its working fine
credit goes to gorbypark who told me this in discord
I'm assuming that your front and back runs in localhost. The documentation says that if the front-end is in the same domain as the back-end, you don't need to use the URL. Since you have the options parameter declared, you can use the default argument window.location in first place:
class WSService {
initializeSocket = async () => {
try {
this.socket = io(window.location, {
transports: ['websocket']
})
console.log("initializing socket", this.socket)
this.socket.on('connect', (data) => {
console.log("=== socket connected ====")
})
this.socket.on('disconnect', (data) => {
console.log("=== socket disconnected ====")
})
this.socket.on('error', (data) => {
console.log("socekt error", data)
})
} catch (error) {
console.log("scoket is not inialized", error)
}
}
emit(event, data = {}) {
this.socket.emit(event, data)
}
on(event, cb) {
this.socket.on(event, cb)
}
removeListener(listenerName) {
this.socket.removeListener(listenerName)
}
}
Don't specify the host/port for socket-io to connect to. It can figure it out on its own.
Per documentation, it tries to connect to window.location if no URL is specified as an argument.
So instead of
this.socket = io(SOCKET_URL, {
transports: ['websocket']
})
Just do
this.socket = io()
I am not sure it works with other arguments. You could try like this
this.socket = io(undefined, {
transports: ['websocket']
})

web scraping for html page but need for repeat on lots link?

I wrote the following code for parse some part of HTML for one URL. I means parse page const URL= 'https://www.example.com/1'
Now I want to parse the next page 'https://www.example.com/2' and so on. so I want to implement a For-Loop manner here.
what is the easiest way that I can use the iteration manner here to
change URL (cover page 1,2,3, ...) automatically and run this code in repeat to parse other pages? How I can use for-loop manner here?
const PORT = 8000
const axios = require('axios')
const cheerio = require('cheerio')
const express = require('express')
const app = express()
const cors = require('cors')
app.use(cors())
const url = 'https://www.example.com/1'
app.get('/', function (req, res) {
res.json('This is my parser')
})
app.get('/results', (req, res) => {
axios(url)
.then(response => {
const html = response.data
const $ = cheerio.load(html)
const articles = []
$('.fc-item__title', html).each(function () {
const title = $(this).text()
const url = $(this).find('a').attr('href')
articles.push({
title,
url
})
})
res.json(articles)
}).catch(err => console.log(err))
})
app.listen(PORT, () => console.log(`server running on PORT ${PORT}`))
Some considerations, if you added CORS to your app, so that you can GET the data, it's useless, you add CORS when you want to SEND data, when your app is going to receive requests, CORS enable other people to use your app, it's useless then trying to use other people's app. And CORS problems happen only in the browser, as node is on the server, it will never get CORS error.
The first problem with your code, is that https://www.example.com/1, even working on the browser, returns 404 Not Found Error to axios, because this page really doesn't exist, only https://www.example.com would work.
I added an example using the comic site https://xkcd.com/ that accepts pages.
I added each axios request to an array of promises, then used Promise.all to wait for all of them:
The code is to get the image link:
const PORT = 8000;
const axios = require("axios");
const cheerio = require("cheerio");
const express = require("express");
const app = express();
const url = "https://xkcd.com/";
app.get("/", function (req, res) {
res.json("This is my parser");
});
let pagesToScrap = 50;
app.get("/results", (req, res) => {
const promisesArray = [];
for (let pageNumber = 1; pageNumber <= pagesToScrap; pageNumber++) {
let promise = new Promise((resolve, reject) => {
axios(url + pageNumber)
.then((response) => {
const $ = cheerio.load(response.data);
let result = $("#transcript").prev().html();
resolve(result);
})
.catch((err) => reject(err));
});
promisesArray.push(promise);
}
Promise.all(promisesArray)
.then((result) => res.json(result))
.catch((err) => {
res.json(err);
});
});
app.listen(PORT, () => console.log(`server running on PORT ${PORT}`));

Add Login node server before another node js server

I have created a login module using node server (ejs engine) listening on port 3000. Upon successful login with that module, i want to redirect that to another node server listening on port 2011 (made using jade engine). the redirect is not working properly.
The working of login module is such that it put an axios post request with username and password on a live website and get a successcode in return. There is no registration required as the authentication is done by that live website.
Both the servers(3000 and 2011) are working fine but the redirect is not working
Can I route the other node app(2011) on the same server with "localhost:3000/welcome" domain?
'use strict'
const express=require("express");
const app=express();
const path=require("path");
const port=process.env.PORT || 3000
const pubdir=path.join(__dirname,"/public");
const bodyParser = require('body-parser')
const axios=require("axios");
// const axiosCookieJarSupport = require('axios-cookiejar-support').default;
// const tough = require('tough-cookie');
// const https = require('https');
// const Cookie=require("request-cookies").Cookie;
// const http=require("http");
// axiosCookieJarSupport(axios);
// const request= require("request");
var urlencodedParser = bodyParser.urlencoded({ extended: false })
const offlineroute=require("./router")
app.set("view engine", "ejs");
app.use(express.static(pubdir))
app.get("/",(req,res)=>{
res.render("index");
})
const url uat="It's a valid url working fine"
const url_uat_auth="Another url working fine"
app.post("/login",urlencodedParser,(req,resp)=>{
const data = {
username:req.body.user_name,
password:req.body.user_pass,
captcha:"121212",
deviceID: null,
}
const apiData={
action: "ACCESSTOKEN",
username: data.username,
password: data.password,
}
axios.post(url_uat, data)
.then((res) => {
// console.log(`Status: ${res.status}`);
console.log('Body: ', res.data);
// console.log("headers",res.headers);
if(res.data.message=='auth')
{
console.log("Successfully logged in");
// app.use("/welcome",offlineroute);
resp.redirect("localhost:2011"); //Help me here.
(async ()=>{
try {
const response = await axios.get(url_uat_auth, apiData);
console.log(response.status);
console.log(response.headers);
} catch (error) {
console.log(error.response.body);
}
})();
}
else if(res.data.message==null && res.data.errorCode=='AUTH_9002')
{
console.log("Wrong username or password");
}
else if(res.data.message==null && res.data.errorCode=='SWEB_9000')
{
console.log("Invalid Captcha");
}
}).catch((err) => {
console.error(err);
});
})
app.listen(port,(req,res)=>{
console.log(`Listening on Port ${port}` );
});
Try to add the full protocol and port:
resp.redirect("http://localhost:2011");

My JSON.parse in app.js doesnt function properly

app.js:
const express = require("express");
const https = require("https");
const app = express();
const port = 3000;
app.get("/",function(req,res){
const url ="https://maps.googleapis.com/maps/api/geocode/jsonaddress=1600+Amphitheatre+Parkway,+Mountain+View,+CA&key=YOUR_API_KEY;
console.log(response.statusCode);
response.on("data",function(data){
var jatin=JSON.parse(data);
console.log(jatin);
})
})
app.listen(port, () => console.log(`Example app listening on port ${port}!`));
Error on Console
app.listen(3000,function(){ console.log("server started on port
3000"); })
server started on port 3000 200 undefined:26
"long_name"
SyntaxError: Unexpected end of JSON input
at JSON.parse ()
at IncomingMessage. (/home/jatin/Downloads/full_stack/Web-Development/maps/app.js:11:21)
at IncomingMessage.emit (events.js:189:13)
at IncomingMessage.Readable.read (_stream_readable.js:487:10)
at flow (_stream_readable.js:931:34)
at resume_ (_stream_readable.js:912:3)
at process._tickCallback (internal/process/next_tick.js:63:19) [nodemon] app crashed - waiting for file changes before starting
The output is visible when I run it on browser but on the console it throws an error.
For some reason JSON.parse() isn't working as expected.
I am trying to make a geocoding API call and in response, it gives me a JSON output...
which when I enter it as a URL on the browser the expected output is received
But when app.js is run on a node express server and when I hit my localhost:3000 I am getting the console error
Apparently the JSON.parse("data") is working but stops unexpectedly. Which leads to error.
You need to have your code to perform JSON.parse on end event instead, like this example form the documentation:
http.get('http://nodejs.org/dist/index.json', (res) => {
const { statusCode } = res;
const contentType = res.headers['content-type'];
let error;
if (statusCode !== 200) {
error = new Error('Request Failed.\n' +
`Status Code: ${statusCode}`);
} else if (!/^application\/json/.test(contentType)) {
error = new Error('Invalid content-type.\n' +
`Expected application/json but received ${contentType}`);
}
if (error) {
console.error(error.message);
// Consume response data to free up memory
res.resume();
return;
}
res.setEncoding('utf8');
let rawData = '';
res.on('data', (chunk) => { rawData += chunk; });
res.on('end', () => {
try {
const parsedData = JSON.parse(rawData);
console.log(parsedData);
} catch (e) {
console.error(e.message);
}
});
}).on('error', (e) => {
console.error(`Got error: ${e.message}`);
});
Notice that this is http.get, but it should be the same for https.get, so in your code the on('data') should be used to assemble the chunks before your perform JSON.parse() on it.
const express = require("express");
const https = require("https");
const app = express();
const port = 3000;
app.get("/", function(req, res) {
const url = "API_URL";
https.get(url, function(response) {
console.log(response.statusCode);
let body = "";
response.on("data", function(data) {
body += data;
});
response.on("end", function() {
console.log(JSON.parse(body));
});
});
res.end("End data response");
});
app.listen(port, () => console.log(`Example app listening on port ${port}!`));
basically .on('end', callback') and .on('data', callback') are event listener to data receive and request end events, and to be able to handle your requests response in node when using http(s).get you have to attache an event listener on data event which is invoked every time your request receives a chunk of the request response, and once the request ended by the service the event end will be invoked stating that there is no more data from the server requested hence the request ended.
as stated in the documentation:
The callback must take care to consume the response data for reasons
stated in http.ClientRequest section.

Execute a javascript till node server runs in NodeJS

I am using NodeJS. I am checking the response status of https://encrypted.google.com/ . I have a file in my project. Let's call it ,
status.js :-
var https = require('https');
https.get('https://encrypted.google.com/', function(res) {
console.log("statusCode: ", res.statusCode);
console.log("headers: ", res.headers);
res.on('data', function(d) {
process.stdout.write(d);
});
}).on('error', function(e) {
console.error(e);
});
Now, I also have server.js file and node is running through it.
node server.js
I want to execute the status.js till the nodeserver runs. That means, it should continously check the status of https://encrypted.google.com/. What is the recommended way to do this ?
server.js :-
const express = require('express');
const bodyParser = require('body-parser');
// create express app
const app = express();
// listen for requests
app.listen(3000, () => {
console.log("Server is listening on port 3000");
});
Use a setInterval and execute the code from status.js. When your status is resolved as you want it, clear the interval via clearInterval.
Ok. I think the adding an event emitter was a bit unnecessary. You can try this out. This is the typescript file. For javascript replace the imports with the respective require statements.
server.ts
import express from "express";
import http from 'http';
import { getHttpsRequests } from "./status";
//Create an http server with the express app
const app = express();
const server = new http.Server(app);
let interval;
// listen for requests
server.listen(4300);
server.on('listening', () => {
interval = setInterval(() => {
getHttpsRequests();
}, 1000);
});
//register a close event on server
server.on('close', () => {
console.log('closing server');
clearInterval(interval);
});
status.ts
var https = require('https');
export function getHttpsRequests() {
//your code goes here
https.get('https://encrypted.google.com/', function (res) {
console.log("statusCode: ", res.statusCode);
console.log("headers: ", res.headers);
res.on('data', function (d) {
process.stdout.write(d);
});
}).on('error', function (e) {
console.error(e);
});
}

Categories