AngularJS handling Server HTTP 403/40X - angularjs

I have standard functions in my frontend AngularJS 1.x application (with ui-route) which looks like the one at bottom.
My question now would be what to do if e.g. HTTP 403 appears. Is there a best practive approach how to redirect to loginpage in AngularJS.
I would be thankful for all hints in this direction.
Thanks a lot!
function getSomethingFromServer(someParameters) {
return $http.get(api_config.BASE_URL + ...', {
}).success(function(data) {
console.log('got data from server');
}).error(function(data) {
console.log('error getting data from server'); // in my case HTTP 403 appears if token is not valid any more
});
}

Take a look at the the $http service in the angular docs and in particular response interceptors - https://docs.angularjs.org/api/ng/service/$http

Related

AngularJS $http post to non existing url 404

This may be one of these questions that doesn't need much explanation i just didn't found the answer elsewhere.
I'm pretty new to AngularJS and NodeJS. I did some tutorials and now i try to put something together.
In nodeJS when i do something like this:
app.get('/db-get-extra-bookings', function(req, res) {
res.json({name: "hello"});
});
than in AngularJS i can GET that response and do something with that even if /db-insert-extra-bookings is not an fysical page
return $http
.get(formURL)
.then(function(response){
// some code
});
But when i want to post something from out of AngularJS to my NodeJs environment
return $http
.post(formJson, JSON.stringify(bookings))
.then(function(response){
//some code
});
NodeJS:
app.get('/db-insert-extra-bookings', function(req, res) {
// do something with the request
});
I got a 404 error in my webbrowser console.
base.js:5 POST http://localhost:3000/db-insert-extra-bookings 404 (Not Found)
It sounds like normal behaviour, but why am i getting a 404 error when i POST to a non existing page, and why am i getting the data like i want when i GET from a non existing page?
Do i really need to make an empty page to post to?
I'm not a expert in NodeJS, but if you want to create a route that answer any HTTP method you should use app.all() instead of app.get(). In your code you are just creating a route for GET requests, that is why it works for a GET and don't work for a POST. Check out this reference
Just to clarify, NodeJS endpoints (GET included) do not need to serve an HTML page to work. You can send any type of HTTP response, e.g. plain text, JSON, HTML, etc - with the appropriate 'Content-Type' header.
In NodeJS routes:
app.post('/db-get-extra-bookings', function(req, res) {
res.json({name: "hello"});
});
Now in your angular code (You don't need to JSON.stringify):
// Change localhost:9000 with your hostname
$http.post('http://localhost:9000/db-get-extra-bookings', bookings)
.success(function (data, status, headers, config) {
// console.log(data);
})
.error(function (data, status, headers, config) {
// console.log(status);
});
Also, remember to restart your NodeJS server for the changes to take effect.

Angular Token based Auth with CORS

I'm trying to create a cross domain request with angular 1.4.7. I'm pretty new to this topic and especially in this scenario I'm not able to find any help via google.
Environment:
I try to call from the angular app A served by www.a.com the restful api's offered by the server B served by www.b.com.
The thing im struggling over is, that I have to authorise myself a via token in the http post. This token constelation should look like:
{
"account": {
"hashcode": "somehashcode"
},
"hashkey": "somehashkey"
};
I tested the api with Postman an it works well, but I'm failing to realise it with angular.
postman successful try picture 1
postman successful try picture 2
To enable cors in my app.js:
.config(['$httpProvider', function($httpProvider){
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common["X-Requested-With"];
}]);
An my request:
$http({
url: 'http://evori-api.azurewebsites.net/api/handshake',
method: 'POST',
data: authtoken,
headers: {
'Content-Type': 'application/json'
}
})
.then(function(data, status) {
console.log(data + status);
}, function() {
});
Any help would be appreciated. Even if you just got an article or blog that explains how such things should be done. I know there is probably just a dumb mistake or something but it drives me crazy.
Thanks a lot.
It seems like the problem wasn't me or my api call. The source of the problem was, that the server didn't handle the OPTION call that leads each cors request.

$httpProvider interceptor not intercepting my API calls

I have an angular application making async requests to an API service. Since a lot of the resources are protected on the API Service, I need to intercept the HTTP requests made to the service. But as far as I can see, the interceptor I have defined only intercept page load requests.
Here is an experimental setup I have come up with to illustrate my problem:
myApp = angular.module('myApp', []);
myApp.config(['$httpProvider', function($httpProvider) {
$httpProvider.interceptors.push(function() {
return {
response: function(response) {
console.log(response);
return response;
}
};
});
});
What I am able to see is that, the interceptor intercepts all calls except the API call as you can see from the attached screen shot showing the console output.
The console output, as you can see from the screen shot below, contains the responses logged when the partial templates have been loaded but not when the GET request was made to the API service.
Why does this happen?
Update
I have changed my setup to include all possible combinations of requests and responses now:
$httpProvider.interceptors.push(function() {
return {
request: function(request) {
console.log(request);
return request;
},
requestError: function(request) {
console.log(request);
return config;
},
response: function(response) {
console.log(response);
return response;
},
responseError: function(response) {
console.log(response);
return response;
}
};
});
Now the interceptor intercepts the message but weirdly shows the status of the caught responseError as:
status: -1
although it clearly is a 401.
Update 2
As it turns out, even 401 responses require the CORS header to be added to it. The problem came up since the REST API I was calling used Spring-CORS library which does not include CORS headers on 401 and 403 responses.
It's a cross-site domain issue because although your using localhost your API call domain is different to the UI's (port 8080 & 8081), have a read of this article for more information. You will need add this header in your webserver:
Access-Control-Allow-Origin: http://foo.example
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

POST Behavior Between $http and Restangular

I have a simple ASP.NET Web API 2 service. I'm new at Angular, but I'm trying to switch from using $http to Restangular. My GET appears to be fine, but my POST is not.
The code looks like this:
$scope.addLift = function () {
$http.post(url, $scope.Lift);
//Restangular.all('lifts').post('Lift', $scope.Lift).then(function (newLift) {
// $scope.getLifts();
//}, function (error) {
// console.log(error);
//});
};
The commented out Restangular code does not work, but the $http.post does and I'm not sure what I'm doing wrong.
If it's helpful, the POST when using Restangular is http://localhost/api/lifts?LiftName=test where in the $http POST request, it does not contain the parameters on the URL line, it seems the data is in the request body.
Someone on another website was kind enough to help me through this. Thought I would post the answer in hopes that it might benefit others.
Restangular.all('lifts').post($scope.Lift).then(function (newLift) {
$scope.getLifts();
}, function (error) {
console.log(error);
});
The additional 'lift' argument was not necessary in the post call.

AngularJS $http interceptors

Javascript code...
commonApp = angular.module('commonApp')
.config(function($httpProvider){
$httpProvider.interceptors.push('myHttpInterceptor');
})
.factory('myHttpInterceptor', function($q, $window){
return {
request: function(config){
console.log('Request started'); // LOG AT REQUEST START
return config || $q.when(config);
}
};
});
I believe that the message should be logged at the beginning of an xhr request.
But I am seeing logs without xhr requests.
Am I misunderstanding the api?
Your plunkr seems to be working fine? There's a good blog post on understanding angular http interceptors you might find useful: http://djds4rce.wordpress.com/2013/08/13/understanding-angular-http-interceptors/

Resources