I am attempting to use a Nodejs server as a proxy server to get around CORS of specific API's, such as darksky.net or googleapis. As shown in my Angular 8 code below, I try to send a get request to my NodeJS server, passing three parameters. Once the NodeJs server has received these parameters, I request the API, but I get a 404 error in return.
Angular code:
this.http.get('search/coords/',
{
params: {
address: this.street,
city: this.city,
state: this.state
}
}).subscribe(data => {
this.lattitude = data['results']['geometry']['location']['lat'];
this.longitude = data['results']['geometry']['location']['lon'];
console.log(this.lattitude);
console.log(this.longitude);
this.coords = {
lat: this.lattitude,
lon: this.longitude
};
});
return this.coords;
}
And here is my current Nodejs/Express code:
const express = require('express')
const path = require('path');
const http = require('http');
const bodyParser = require('body-parser');
var request = require('request');
const app = express();
var url = "";
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({'extended': 'false'}));
app.use(cors());
app.get('search/coords/', function (req, res) {
var street = req.query.address;
var city = req.query.city;
var state = req.query.state;
url = "https://maps.googleapis.com/maps/api/geocode/json?address=" + street + "," + city + "," + state + "&key=blah/"
request(url, function(error, response, body) {
if (!error && response.statusCode == 200) {
var info = JSON.parse(body);
res.send(info);
}
})
});
Specifically, I receieve a GET 404 not found error and an ERROR HttpErrorResponse {headers: HttpHeaders, status: 404, statusText: "Not Found", url: "http://localhost:4200/search/coords/?address......." I'm new to angular and nodejs, so any help would be much appreciated.
There are two problems:
First is that you did not start the Node server
Second is that if you call this.http.get('search/coords', ...) then the default domain for that request is the current one, which is http://localhost:4200 and that is not you Node server port.
To make it work, you need to address both of the above.
So firstly, add this code to the Node.js server file (at the very bottom) to make it listen on some port:
app.listen(3000, () => {
console.log('Listening on port', 3000);
});
Then, modify your Angular code to make it look like this:
this.http.get('http://localhost:3000/search/coords/', ....);
It should work that way.
Related
Hello i have two NodeJS running on my sever
please this is only a dev machine not production so i know parsing the form data etc etc
App.js - Backend Express Sever running on port 4000
index.js - Front End PUG/Express running on port 8000
i can access the frontend on something.mydomain.com
but when i try to ajax the backend with 'POST' to localhost:4000/Whatever/Whatever
it doesnt allow me to.
as in it tries to load locahost from the WWW external not internal
login.js
const serverurl = "http://localhost:4000";
$(document).ready(function () {
$('#login').click(function () {
var data = {};
data.username = $('#inputusername').val();
data.password = $('#inputpassword').val();
$.ajax({
url: serverurl+'/user/login'
, type: 'POST'
, data: JSON.stringify(data)
, contentType: 'application/json'
})
.done(function (data) {
if (data[0].response == '1') {
alert("Logged In");
Cookies.set('user', data[0].name);
Cookies.set('location', data[0].location);
Cookies.set('role', data[0].role);
$(location).attr('href', '/home');
} else if(data[0].response == '0') alert("Username or Password Incorrect")
});
});
frontend request image
Any help will be appreciated
You got CORS error. You can reach more info about it.
My solution is using for Express.js CORS package
Your main js file should be like:
// app.js
const express = require('express')
const cors = require('cors')
const app = express()
app.use(cors())
I am using post method in nodejs
Well it is working fine when I run it using postman
but when I run it in my browsers it shows error
Cannot GET /listUsers
and
listUsers:1 GET http://localhost:8081/listUsers 404 (Not Found)
this
here is my node js code
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended:false}));
app.post('/listUsers', function (req, res) {
var f = parseInt(req.body.f);
console.log("hello" + f);
var l = parseInt(req.body.l);
var sum = Number(f + l);
res.send('The sum is: ' + Number(sum));
})
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)
})
here is my jquery code from where I am sending data
usid();
function usid(med){
var f = "my new name";
$.ajax({
crossDomain: true,
url:"http://localhost:8081/listUsers",
method:"POST",
data:{med,f:f},
success:function(data,status){
console.log("send");
}
})
}
can I get where I am doing mistake?
You are not submitting any form/storing any resource. What you are trying should ideally be done with GET.
Reasons it is not working with browser:
Visiting a page by changing url is a GET method. You do not have a GET method defined in your app for this route. Only one POST method.
What you can do:
Change POST to GET both in server and your AJAX. Change both methods accordingly. You will then have to pass query params(google something and everything after the question mark is how query Params work).
I am trying to retrieve weather API from external server and when I am console logging particular data of weather API, it's also showing on my command prompt.
But when I am using get method to show that data on browser I am only able send string data like "description": moderate rain and not number data like "temp": 27
it the crash the app.
Node js code:
//jshint esversion:6
const express = require("express");
const app = express();
const https = require("https");
app.get("/", function(req, res) {
const url = "https://api.openweathermap.org/data/2.5/weather?q=mumbai&appid=d88391210768983e6be06cdd76bdcde3&units=metric";
https.get(url, function(response) {
console.log(response.statusCode);
response.on("data", function(data) {
const weatherData = JSON.parse(data);
const temp= weatherData.main.temp;
const description= weatherData.weather[0].description;
console.log(temp);
console.log(description);
res.send(temp);
});
});
});
app.listen(3000, function() {
console.log("Server is running on port: 3000");
});
You should ideally return a json.
It can be:
res.send({temp: temp, description: description});
The res.send has to return a string/object/array/buffer.
You could do something like:
res.status(200).send(temp)
But sending json response is preferable, and you can scale it as well.
Another hack kind of solution is:
res.send("" + temp)
I'm building a react app
In one component I'm writing this GET request which works:
In another component I'm writing this POST request:
Which then returns this 404 error:
And I have no idea how my GET works but my POST returns 404:not found when I'm requesting the same file both times?
UPDATE:
I'm running a node.js server now but it's a bit of a frankenstein's monster as this really isn't an area I have an understanding of. Does anyone know what I'm doing wrong?
// Server setup from node.js website
const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World\n');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
// Trying to listen for data from React app to feed into JSON (broken)
var express = require("express");
var myParser = require("body-parser");
var app = express();
app.use(myParser.urlencoded({extended : true}));
app.post("/scene-setup.json", function(request, response) {
console.log(request.body); //This prints the JSON document received (if it is a JSON document)
});
app.listen(3001);
// Updating JSON file with "obj" (working)
var jsonfile = require('jsonfile')
var file = './scene-setup.json'
var obj = {name: 'JP'}
jsonfile.writeFile(file, obj, function (err) {
console.error(err)
})
Axios is used for making HTTP requests. So, you should have a backend server running that can handle these requests. I am not sure what exactly is the data that you want to save. If you need access to that data, should be saving it on the backend.
If you want to save some data just on the client side, HTML5 filesystem API might be something you want to look at. It can manage some data in the limited sandboxed part of user's filesystem.
I want to pull a URL from the DB and use it as the proxied URL. However the setup I've come up with initializes a new BrowserSync server for each URL, using incrementing port numbers.
Is there a way to accomplish this without initializing a new BrowserSync server every time?
Or should I be using another approach?
var bs = require("browser-sync");
var express = require("express");
var router = express.Router();
var app = express();
router.get("/", function(req, res){
var proxyUrl = getUrl() //get url from db (www.example.com)
bs.create("bs1").init({
notify: false,
open: false,
ui: false,
port: 10000,
proxy: proxyUrl
});
res.send();
});
app.use(router);
app.listen(8080, function(){
console.log('listening on *:8080');
});
The above is fine(ish) but is it good practice to be initializing a new server for every URL (potentially thousands)?
And is it safe to be exposing a new port number to every user of the system? (Can I mask this with a subdomain?)
Update
My end goal is to use a unique subdomain to refer to each proxy url.
For example:
sub1.mysite.com proxies www.example.com,
sub2.mysite.com proxies www.example2.com
Browser-sync will not work as the proxy is tie to server setup.
I use following packages:
express
express-http-proxy
vhost (express vhost)
const port = 8080;
var app = require('express')();
var proxy = require('express-http-proxy');
var url = require('url');
var vhost = require('vhost');
app.listen(port);
/* Assuming getUrl() will return an array of sites */
// var sites = getUrl();
// DO NOT put '/' at the end of site
var sites = [
'http://www.bing.com',
'http://samanthagooden.com',
'http://www.courtleigh.com'
];
var i = 0;
sites.forEach(site => {
i++;
var subDomain = 'sub' + i + '.mysite.com';
app.use(vhost(subDomain, proxy(site, {
forwardPath: (req, res) => url.parse(req.url).path,
intercept: (rsp, data, req, res, callback) => {
if (res._headers['content-type']) {
var contentType = res._headers['content-type'];
if (
contentType.indexOf('text') !== -1 ||
contentType.indexOf('javascript') !== -1
) {
// Replace link if content-type = text or javascript
var reg = new RegExp(site, 'g');
res.send(data.toString().replace(reg, ''));
} else {
res.send(data);
}
} else {
res.send(data);
}
}
})));
console.log(subDomain + ':' + port + ' proxy: ' + site);
});
The above example will create following proxies:
sub1.mysite.com:8080 proxy: www.bing.com
sub2.mysite.com:8080 proxy: www.example.com
Maybe I'm misunderstanding what you are trying to do, but Browsersync and express seems a bit overkill in this case, why not just use node-http-proxy with the native http module?
var http = require('http')
var httpProxy = require('http-proxy')
var options = ...
var proxy = httpProxy.createProxyServer(options)
var server = http.createServer(function (req, res) {
var proxyUrl = getUrl()
proxy.web(req, res, { target: proxyUrl })
})
server.listen(8080, function () {
console.log('listening on *:8080')
})
As per me If you want SAAS service using proxy is not the good idea to go is what am thinking.. if you are going with proxy for each client will create process with new port... My Solution is to create node server with listen localhost and map *.domain.com to the server..
If you are using individual database for each client :-
in node logic get cname from request host and use that reference to connect database.
Final Controller code would be..
var express = require('express');
var router = express.Router();
var MongoClient = require('mongodb').MongoClient;
/* GET home page. */
router.get('/', function(req, res, next) {
var client = req.subdomains[0];
console.log(client);
MongoClient.connect('mongodb://localhost:27017/'+client, function(err, db) {
if (err) {
throw err;
}
db.collection('app1').find().toArray(function(err, result) {
if (err) {
throw err;
}
console.log('data');
console.log(result);
});
});
res.render('index', { title: 'Express' });
});
module.exports = router;
~
~
In future if you get more clients you can implement node cluster or standard Ubuntu cluster using webservice