How to catch http error response in Angular - ajax

Background
My Angular application communicates with a database through a set of API endpoints.
"user/authenticate" endpoints accepts username and password and returns a success (200) or a bad request (400) http response.
Controller
authService.login(email, password)
.success(function (response) {
/* go to application */
})
.error(function (response) {
/* display proper error message */
});
auth Service
factory.login = function(email, password) {
return $http({
method: 'POST',
url: "http://myserver/user/authenticate",
data: $.param({email: email, password: password}),
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
});
}
Problem
When username and password fails and API returns 400 response, even though I'm catching the error and I'm displaying a proper message to user, the error appears in browser console.
POST http://myserver/user/authenticate 400 (Bad Request)
Can I handle errors in a better way?

Try this
factory.login = function(email, password) {
return $http({
method: 'POST',
url: "http://myserver/user/authenticate",
data: $.param({email: email, password: password}),
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).then(function (response) {
/**Check here your status code 400 if you found that status code is 400 the reject the promise**/
if (statuscode !==400) {
return response.data;
} else {
// invalid response
return $q.reject(response.data);
}
}, function (response) {
// something went wrong
return $q.reject(response);
});
}
and then use following code
authService.login(email, password)
.then(function (response) {
/* go to application */
},function(error) {
console.log(error); /* catch 400 Error here */
});

Related

Send an Authenticated Request

I have an MVC project secured with a asp.net identity:
This is my Login function:
self.login = function () {
event.preventDefault();
if (!$('#formLogin').valid()) {
return false;
}
var loginData = {
grant_type: 'password',
username: self.userName(),
password: self.password()
};
$.ajax({
type: 'POST',
url: '/API/Token',
data: loginData
}).done(function (data) {
// Cache the access token in session storage.
sessionStorage.setItem(tokenKey, data.access_token);
self.authenticate();
//change status of Login button to Logout
self.redirect('Users');
}).fail(showError);
}
self.authenticate = function () {
self.token = sessionStorage.getItem(tokenKey);
var headers = {};
console.log(self.token);
if (self.token) {
headers.Authorization = 'Bearer ' + self.token;
}
$.ajaxSetup({
headers: headers
});
}
That works fine, I get the token successfully and the headers are set up correctly.
The problem is that when I try to send a request- for example:
self.getUsers = function () {
$.get("/API/Users/GetUsers/");
}
I get a 401 error from the server:
"message": "Authorization has been denied for this request."
What am I doing wrong?
According to the official documentation of the jQuery.ajax, use this to set custom headers of each request:
$.ajaxSetup({
beforeSend: function(xhr) {
xhr.setRequestHeader('Authorization', '...');
}
});

Getting blocked response even if status code 200 is returned

I have MVC web app and I am consuming some WEB API with AJAX calls. I try to login, so I send username and password, to get the needed info (token etc.).
var loginData = {
grant_type: 'password',
username: 'SomeName',
password: 'SomePass'
};
$.ajax({
type: 'POST',
url: '/Token',
contentType: "application/x-www-form-urlencoded; charset='utf-8'",
data: loginData,
success: function (response) { // 200 Status Header
localStorage.setItem('token', response.access_token);
alert('Success!');
},
error: function (response) { // 500 Status Header
alert('Error!');
}
});
The problem is - After the request is send, the server returns the response with all the informations, but it is somehow blocked.
It returns status code - 200 with all the information but the response is blocked/aborted
Session properties (provided by Fiddler)

Ajax call to login to spring secrurity failed

I am trying the following ajax call to login to spring
$.ajax({
url: "http://localhost:8080/context/j_spring_security_check",
data: { j_username: 'user_name' , j_password: 'user_pass' },
type: "POST",
beforeSend: function (xhr) {
xhr.setRequestHeader("X-Ajax-call", "true");
},
success: function(result) {
// ..
},
error: function(XMLHttpRequest, textStatus, errorThrown){
$("#ajax_login_error_" ).html("Bad user/password") ;
return false;
}
});
This is doesn't work, because the username and password are not passed to the UsernamePasswordAuthenticationFilter. When I debug the request they are both null. In other cases when I login, I can see my user name and password in this filter.
give exception for path (j_spring_security_check) in security filter as
final String contextName = ((HttpServletRequest) request).getContextPath();
final String requestURI = ((HttpServletRequest) request).getRequestURI();
if (requestURI.equals(contextName+"/j_spring_security_check"){
chain.doFilter(request, response);
}
That means you should give exception for login url
You need to override SimpleUrlAuthenticationSuccessHandler. See similar questions here

While converting from jquery to angularjs why am I getting this error?

Jquery Code
$.ajax({
url: '/ad_creation/get_campaign_objective/'+id,
dataType: 'text',
success: function(response) {
var campaign_objective = 'Error. Please refresh and try again.';
if (response == 'WEBSITE_CONVERSIONS')
campaign_objective = response;
if (response == 'WEBSITE_CLICKS')
campaign_objective = response;
$('select[name=campaign_objective]').val(response).hide();
$('#existing-campaign-objective').html(campaign_objective).show();
$('#campaign-objective-select').show();
if (campaign_objective == 'WEBSITE_CONVERSIONS'){
// Show pixel block again.
$('#select-pixel').show();
}
hideAjaxLoader('existing-campaign-loader');
},
error: function(xhr, ajaxOptions, thrownError) {
console.log('Invalid response', thrownError, xhr, ajaxOptions);
hideAjaxLoader('existing-campaign-loader');
}
});
Angularjs code
$http({
method:'get',
dataType:'text',
url:'/ad_creation/get_campaign_objective/'+Number(id)
})
.success(function(data){
console.log(data);
})
I get the error Unexpected token w. I have also tried not casting the id to number but still get the error.
Check the content-type of the response headers.
If it is 'application/json' angular tries to parse the response.
The error might be because of it.

WebAPI redirect not working?

I'm trying the following:
[System.Web.Http.AcceptVerbs("PUT")]
public HttpResponseMessage MakePost(PostDto post) {
try {
var response = Request.CreateResponse(HttpStatusCode.Redirect); // tried MOVED too
response.Headers.Location = new Uri("google.com");
return response;
} catch (Exception e) {
ErrorSignal.FromCurrentContext().Raise(e);
return Request.CreateResponse(HttpStatusCode.InternalServerError, e);
}
}
Which seems to be partially working - when this is called, I see the POST request in chrome debugger. Nothing appears in the Response tab, but then I see a GET request sent to the new URI, yet the page never changes, and my AJAX call throws an error:
var options = {
url: postUrl,
type: type,
dataType: 'json',
xhrFields: {
withCredentials: true
}
};
return $.ajax(options)
.done(function (response) {
// do stuff
})
.fail(function (response) {
alert('error) // this gets hit - shouldn't the browser have redirected at this point?
}).complete(function () {
// stuff
});
};
If I inspect response, I see a Status 200 "OK".... I'm so confused.
What am I doing wrong?
This happens because the code issuing the AJAX request follows the redirect, not the browser. This will then fail because the AJAX request tries to access a different domain. If you want to redirect the browser, you should return some JSON result or a custom HTTP header, manually pick this up in your jQuery, and do the redirect there.
In your controller:
var response = new HttpResponseMessage(HttpStatusCode.OK);
response.Headers.Add("FORCE_REDIRECT", "http://google.com");
Then add a success callback to your AJAX call:
success: function(data, textStatus, jqXHR) {
if (jqXHR.getResponseHeader('FORCE_REDIRECT') !== null){
window.location = jqXHR.getResponseHeader('FORCE_REDIRECT');
return;
}
}
In the past, I've wrapped the controller result up in a custom action result class for reuse.

Resources