Node/Express not finding route for Angular http json post (404) - angularjs

I'm developing a new Angular client which should communicate with my Node/Express server. I'm currently trying to develop the first step aka the login. This should be an http json post. It turns out that every single time I execute that post from the client to the server, the Node/Express server doesn't find the route for my path.
On the console log of the server, for my post json request I find following stacktrace:
OPTIONS /api/auth/facebook/mobile 404 274.092 ms - 1980
Node/Express side:
My route
app.post('/api/auth/facebook/mobile', authenticationHandler.handleFacebookMobileLoginRequest);
Body parser for json is defined:
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
On the Angular client side, I do:
http({
method: 'POST',
url: 'http://192.168.1.101:3000/api/auth/facebook/mobile',
headers: { 'Content-Type': 'application/json; charset=UTF-8;' },
data: {fbToken: authResponse.accessToken}
})
.then(function (response) {
...
Fun facts:
Same route works fine when I call it from a Java app or and Android native app, like
final JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, SERVER_URL + "/api/auth/facebook/mobile", params, jsonRequestListener, errorListener);
On my Angular client, when I change data with params then it works, the route is found...but I mean that doesn't make any sense. Moreover, I've got then a problem on the Angular client side, the answer isn't processed respectively the answer never land in the .then(... function. Which again works well in other clients.
Anyone got an idea, a clue or should I call Dr. Strange?

Possible browser preflighted request CORS issue?
Try using CORS module in Node.js server:
var cors = require('cors')
app.use(cors());

Related

Cors issue i also set the proxy in pkg.json due to cors and set the api according to it but this error is not remove

GET http://localhost:3000/api/fetch?search=12312321 404 (Not Found)
cors issue in Reactjs and node js
i use the proxy method in Reactjs but can't get rid from it please help me
proxy
"proxy":"http://localhost:5000/"
tried both
"proxy":"http://localhost:5000"
express
RegisterRoute.route('/fetch/:id').get( ( req , res) =>
{
console.log("called by someone ",req.params.id);
res.send("okey will");
});
Reactjs function which will call the backend api
FetchNotification(){
axios({
'method':'GET',
'url':'api/fetch',
'headers': {
'content-type':'application/octet-stream',
'x-rapidapi-host':'example.com',
'x-rapidapi-key': process.env.RAPIDAPI_KEY
}
,
'params': {
'id':'12312321'
},
})
}
when i simply call axios.get it perfectly work but when i give params to it it gives the error xhr:178 404 not found
a simple server which also returns the same result
const express = require('express');
const cors= require('cors');
const app= express();
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: false }));
// parse application/json
app.use(bodyParser.json());
app.use('*',cors());
app.get('/fetch/:id',(req , res) => {
console.log("calling",req.params.id);
});
app.listen(5000);
I can see that you're using Nodejs as server side. So, you can try changing following line
app.use('*',cors());
to
app.use(cors());
If this doesn't solve the issue, you can try adding a google chrome extension for CORS (Most probably). In this way, you'll not need any proxies being set for running servers.
Also, you need to do a small change in URL, instead of calling
'url':'api/fetch'
you need to provide an id in your call, because the backend api is accepting a parameter
'url':'api/fetch/some_id'
I feel there are multiple issues. I'll try to address them one by one.
Firstly, if you are proxying your requests correctly (which I think you are as per your package.json), then you'd not require the cors package. So you can get rid of that package.
Read more about why you shouldn't let all incoming request bypass the CORS check from security point of view -> Is it safe to enable CORS to * for a public and readonly webservice?
Now secondly, the url which you've specified on the frontend is 'url':'api/fetch', which means browser will make a call to http://localhost:3000/api/fetch?search=12312321 which it correctly did as seen in your error statement for 404.
Specifying the proxy as "proxy":"http://localhost:5000" in package.json means that now you are making requests to http://localhost:5000 instead of http://localhost:3000, but the browser would still think its http://localhost:3000. That's the whole purpose of proxying and how you kinda fool browser to do CORS without throwing any error.
But because on your server, you are listening to app.get('/fetch/:id',(req , res) instead of app.get('api/fetch/:id',(req , res), it doesn't matches with this URL as you have not explicitly handled requests starting with /api in some separate router module either.
So you should either update the url in the axios call to url':'/fetch while the proxy value in package.json is "proxy":"http://localhost:5000" or url':'fetch and "proxy":"http://localhost:5000/" respectively. Notice how i've used the /
OR
You can update the URL on the express end to app.get('api/fetch/:id',(req , res)
Lastly, whenever you receive a request, you need to return some value(string or JSON or even status code) as result.
In your case, you've simply console.log("calling",req.params.id); and didn't send back any response to the UI.
So even if your 404 would resolve after fixing the URL, you'd bump into request timeout error (408) as your UI will keep waiting for a response from the server while you didn't send any.
So you should do something like this maybe:
app.get('api/fetch/:id',(req , res) => {
console.log("calling",req.params.id);
res.send("It worked");
});
Notice how there's a response being sent back -> https://expressjs.com/en/starter/hello-world.html
If you don't want to send back a response, then you can simply return status like 200, 504 etc.
if you apply below code in backend/server i thing it will debug.
app.get('api/fetch/:id',(req , res) => {
console.log("calling",req.params.id);
res.send("It worked");
});

How do I fix a network error received from axios response reactjs

I'm making a post request using axios in reactjs after users login. Here it is:
axios.post('https://localhost:3000/api/login/authentication', {
email: email,
password: password
})
.then(response => {
this.props.history.push('/Main')
})
.catch(error => {
console.log(error)
})
It goes in the error and I log it to the console. This is what I get:
Error: "Network Error"
createErrorhttp://localhost:3000/static/js/0.chunk.js:26742:15 handleErrorhttp://localhost:3000/static/js/0.chunk.js:26293:14
Also in case it's any help, I get this warning before the error:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://localhost:3000/api/login/authentication. (Reason: CORS request did not succeed)
Can anyone please help me solve this issue? Thanks in advance!
If you're using a front-end application that makes request to a back-end API, you need to include certain headers in the API server if the API server is running on a different port.
For example, if you're serving a ReactJS application with webpack in development mode, webpack acts as a server, sending the reactJS application to the client. Then, making requests to the API server will require that the API server, running on a different port, include Access-Control-Allow-Origin headers in all http responses.
Basically, before generating every response, you need to set 'Access-Control-Allow-Origin' to localhost:<port you visit in the browser>.
In a basic express app, you can paste this in your app.js file, for example:
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Origin', 'http://localhost:3001');
res.header(
'Access-Control-Allow-Headers',
'Origin, X-Requested-With, Content-Type, Accept'
);
next();
});
Note: If you may need to change http://localhost:3001 to match the port you visit in the browser.
EDIT: OP is not using express, but is using Webpack. The question is: What is an express-agnostic solution?
Answer: The solution is still the same: regardless of what API server you are using, just set the response headers for every response.
There is another solution that involves Webpack, though:
In the package.json file of your front end code that's being served with webpack, add the following: "proxy" :"http://localhost:<port API server is running on>"
For example, is webpack is serving your front end app to localhost:3000 and your api server is running on localhost:3001, then the proxy in package.json would be:
"proxy":"http://localhost:3001"
You can add the CORS header in webpack dev server config as follows:
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers': '*',
},
This will add these two headers in your response. Hence solve your problem. However, when your services run on a different server other than your local machine, these headers need to be added in server response.
The very first thing that i am figuring out in your code is that you are using 'https' but it should be only 'http'to make request, because local host uses http.
2)This might be due to cors, Before making any requests , the browser sends a pre-flight request to the API server to know that "This website has been allowed to access your resources or not", so using cors and specifying origin which can access API resources will solve this problem.

calling Https url on Http get request angularjs

I have a Https url and want to send request to get data from that URL , scenario 1:
from my browser If I hit the Url i get the response whereas from my Angularjs App I get always an error 401 , but if I hit the Api from browser I always get the correct response
for security reasons I couldn't use Url here but what I want is to:
$http({
method: "GET",
url: "https://urlAdresss/",
headers: {
"Accept-Language": "en-US, en;q=0.8",
"Content-Type": "application/json;charset=UTF-8"
},
}).then(function (_response) {
console.log(_response
}
I always get unauthorized I am network as well as On console any help will be greatly appreciated ,
but If I hit the same Url from browser I get the response It means the backend is working fine
I think I am missing something in my get request that's why getting the error
It seems a CORS (Cross-Origin Resource Sharing) issue.
In AngularJS side, you should use the following configuration in order for $http service to automatically send authorization headers to http requests.
var app = angular.module('app', [])
.config(function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
$httpProvider.defaults.withCredentials = true;
});
And in backend you should specify explicitly allowed origins (eg. http://localhost:8888).
Also, note some points from here.
If you want to allow credentials then your Access-Control-Allow-Origin must not use *.

Angularjs "HTTP/1.1 401 Unauthorized" error in chrome

I have an angularjs application which is consuming a WebAPI created using WCF.
Angularjs application is making call to a WebAPI to fetch client details.
When i run both the projects (angularjs and WCF project) on my local machine. Everything works fine.
After deploying the project on development server I am facing issue while testing my angularjs application in chrome. Chrome fails to load the client details.
I checked the requests made by angularjs application using fiddler. I found that there are two calls made my angularjs application to webAPI, even though in code there is only one call in code,
Following is the code used in angular app
return $http({
method: "GET",
withCredentials: true,
url: $rootScope.models.ServiceURL + "/ServicerClient?clientName=" + searchTextSmallLetters,
dataType: "json",
headers: {
'Content-Type': 'application/json; charset=utf-8'
}
});
First request logged in Fiddler :
GET /PXTRAService.svc/ServicerClient?clientName=volvo HTTP/1.1
First request retunrs following error :
HTTP/1.1 401 Unauthorized
Next request logged in Fiddler has Security section in request header:
GET /PXTRAService.svc/ServicerClient?clientName=volvo HTTP/1.1
Second request retunrs the expected result.
Same scenario is occuring in IE, but IE angular application redeners the fetched results correctly.
Is there any way to fix this issue in chrome?

Webpack not accepting POST requests

I'm currently working on an Angular 2 web application which communicates with an API. In the application the user is able to choose a payment option and the API will return the url to the payment service.
The problem is that the payment service uses POST to go to the confirmation page which WebPack does not accept (for some reason it only allows GET requests) and we get the following error:
Cannot POST /selection/payment-method
Does anybody know how we could configure that WebPack allows POST requests also? I've contacted the payment provider but it is not possible to do a GET request instead of POST.
Thanks
Based on #Sven's answer, modification to the setup so that it works for POST all throughout
Add dependencies on body-parser, sync-request and add require dependencies on both in your webpack.config.js
var bodyParser = require('body-parser');
var request = require('sync-request');
In devServer part of webpack.config.js
devServer: {
setup: function(app) {
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.post(/^\/(URL1|URL2|URL3)\//, function(req, res) {
var serviceCallResponse = request('POST', 'your app server url here' + req.originalUrl, {
json:req.body
});
res.send(serviceCallResponse.getBody('utf8'));
});
},
proxy: {
'*/other URLs proxy/*': 'your app server url here'
}
}
Change URL1/2 to the URLs you want to proxy and you place your app servers address.
This will work for all sorts of POST request proxy (working on json payload)
A hackish way to at least not get 404 errors is to proxy requests to /selection/payment-method and send back an empty response (or whatever content you want, I think that res is an instance of Express's Response class) for those, by adding the following to webpack.config.js:
devServer: {
proxy: {
'/selection/payment-method': {
bypass : (req, res) => res.end()
}
}
}
Documentation here.
Thanks to #robertklep who send me the link to the proxy documentation we found a way to deal with it. What we needed to do was instead of handling the POST request we needed to transform it someway into a GET. After reading some more of the documentation we came across the setup: property for your webpack-dev-server configuration.
With the setup: property you get the expressjs object and you are able to catch urls before it hits the route that says Cannot POST /url/to/page.
We ended up with this:
devServer: {
setup: function(app) {
app.post('/selection/payment-method', function(req, res) {
res.redirect('/selection/payment-method');
});
},
}
This way we got a GET request instead of POST and our application does an API request to check if the payment succeeded or not.
This is only used in development!
The Webpack-dev-server is only intended as your front-end server only, eg. to serve your static assets. Therefore only GET requests are supported.
If you would want to use a proxy or backend server, then you should implement this. You can use Express for this.
See how you can setup basic routing.

Resources