I am using Ajax to login a user into the system.
Ajax success will always run the else statement even if the server returns true Boolean.
In case the login credentials were valid the else statement would run and login failed will show up, but if I refresh the page the user will be logged in.
Basically the if(response) never gets ran even though it is true.
$(function(){
$('#loginButtonIdHead').click(function() {
$.ajax({
url: 'localhost/landing/login',
type: 'POST',
data: {
email: $('#defaultForm-email1').val(),
password: $('#defaultForm-pass1').val()
},
success:function(response) {
if(response){
$('#messageId').text("Login Successful");
} else {
$('#messageId').text("Login Failed");
}
}
});
});
});
The $.ajax() method uses anonymous functions for the success and error callbacks. This version is easier to write, and likely easier to maintain:
$(function(){
$('#loginButtonIdHead').click(function(){
$.ajax({
url: 'localhost/landing/login',
type: 'POST',
data:
{
email: $('#defaultForm-email1').val(),
password: $('#defaultForm-pass1').val()
}, success:function(response) {
$('#messageId').text("Login Successful");
},error: function () {
$('#messageId').text("Login Failed");
}
});
});
});
So if the login are incorrect you should be getting 403 forbidden status from the login api call and that would call the error callback.
Moreover, it's not a good approach to give errors on 200 success status. So the backend developer must update it to the appropriate statuses.
Thanks.
Related
What I am trying to do:
1. Initially gives an ajax request to the server based on some inputs
2. The server returns a job id generated by RQ (Python-rq)
3. Based on the job id ajax request made to a url constructed with the jobid regularly till a valid response is obtained
What I have:
$.ajax({
type: "POST",
url: "/start",
data:{crop: valueCrop, state: valueState, variablemeasure: valueVariable, unit:unitMeasure, from:yearFrom, to:yearTo},
success: function(results) {
console.log(results);
var jobId='';
jobId = results;
function ajax_request() {
$.ajax({
type: "GET",
url: "/results/" + jobId,
dataType: "json",
success:function(xhr_data) {
if (xhr_data == {"status":"pending","data":[]}){
console.log("Waiting for response");
setTimeout(function() { ajax_request(); }, 2000);
} else {
console.log(xhr_data);
}
},
error:function(error) {
console.log(error)
}
});
}
},
error: function(error) {
console.log(error)
}
})
Is this even possible? I am not getting any output at all on the console although the rq says the job is finished. I think it is not entering that if loop. When I visit the "/results/jobId" url I am able to see the result.
Please help.
I see a few bugs in this code. First of all, you have defined the function ajax_request(). But you are not calling it. You can call it at the end of its definition.
Secondly, this code is problematic:
if (xhr_data == {"status":"pending","data":[]})
The object notation creates another object which is definitely not equal to xhr_data.
You can do:
if (xhr_data.status === "pending")
I use this code for a basic anthentification of REST API. Unfortunately, when the user/pass is wrong Google Chrome displays a popup. Firefox does not do that.
$.ajax({
type: "GET",
url: "/ad",
dataType: 'json',
async: false,
username: 'username',
password: 'password',
success: function (){
alert('success');
return false;
},
error: function(){
alert('error');
return false;
}
});
Edit 1 :
I use Laravel Framework
If you don't have server control, there is no (at least not known to me) way to prevent that. If you DO have server control you can do two things:
Change the response status code from standard 401 to something else. However, this is commonly not known as best practice since the status code does then not state the actual issue (authentication error).
Change the response header WWW-Authenticate: Basic realm="your_realm" to a custom value like WWW-Authenticate: x-Basic realm="your_realm" (Note the x-there!).
That should prevent any default login handling.
Update 1
As for using Laravel this would be an example of setting the correct response header WWW-Authenticate (changed Basic to x-Basic):
Route::filter('auth', function()
{
$credentials = ['email' => Request::getUser(), 'password' => Request::getPassword()];
if (!Auth::once($credentials)) {
$response = ['error' => true, 'message' => 'Unauthorized request'];
$code = 401;
$headers = ['WWW-Authenticate' => 'x-Basic'];
return Response::json($response, $code, $headers);
}
});
I think you can pass the username and password in the URL instead for HTTP authentication.
Give this a shot:
$.ajax({
type: "GET",
url: "http://username:password#whatever.com/ad",
dataType: 'json',
async: false,
success: function (){
alert('success');
return false;
},
error: function(){
alert('error');
return false;
}
});
I have an API controller that returns a HttpStatusCodeResult 200 if it worked and 500 if they weren't able to register. The problem is .done and .fail will both be called no matter what status code is returned. However the information is posted or not posted correctly. Here is my post function. Any ideas what could be causing this would be greatly appreciated?
function register() {
$.post("../api/Register",
{
'Email': $("#rEmail").val(),
'Password': $("#rPassword").val()
})
.done((function () {
alert("Thank you for registering!");
})())
.fail((function () {
alert("Email already exists");
})());
}
Edit: The problem is that it was reloading the page when jquery.unobtrusive is supposed to prevent that from happening. The fix or workaround was changing it to a button and not a form.
Instead of passing the anonymous functions you were invoking it as a IIFE by adding () at the end of the function
function register() {
$.post("../api/Register", {
'Email': $("#rEmail").val(),
'Password': $("#rPassword").val()
}).done(function () {
alert("Thank you for registering!");
}).fail(function () {
alert("Email already exists");
});
}
The problem is you're immediately executing the functions that are getting passed to done and fail. That's causing these functions to be executed right then and there.
So just pass the function itself by changing this
.done((function () {
alert("Thank you for registering!");
})())
to this
.done(function () {
alert("Thank you for registering!");
})
You really shouldn't be sending an http status of 500 on an expected registration failure such as "email already exists" condition... this should be handled by a parameter that denotes success / failure as part of a 200 response.
You can handle unexpected internal server errors (status 500) using success or error callbacks like so:
$.ajax({
url : "../api/Register",
type : "post",
data : {"Email" : "you#example.com", "Password" : "pw"},
dataType : "json",
success : function(response){
// handle http 200 responses
if(response.registrationApproved){
alert("Thank you for registering!");
}else{
alert("email exists");
}
},
error : function(){
// handle 500 or 404 responses
alert("server call failed");
},
complete : function(){
// if needed.. this will be called on both success and error http responses
}
});
I am trying to POST some data to my ASP.Net MVC Web API controller and trying to get it back in the response. I have the following script for the post:
$('#recordUser').click(function () {
$.ajax({
type: 'POST',
url: 'api/RecordUser',
data: $("#recordUserForm").serialize(),
dataType: 'json',
success: function (useremail) {
console.log(useremail);
},
error: function (xhr, status, err) {
},
complete: function (xhr, status) {
if (status === 'error' || !xhr.responseText) {
alert("Error");
}
else {
var data = xhr.responseText;
alert(data);
//...
}
}
});
});
The problem with this script is that whenever I try to post the data, the jQuery comes back in "error" instead of "success".
I have made sure that there is no problem with my controller. I can get into my api method in debug mode whenever the request is made and can see that it is getting the data from the POST request and is returning it back. This controller is quite simple:
public class RecordUserController : ApiController
{
public RecordUserEmailDTO Post(RecordUserEmailDTO userEmail)
{
return userEmail;
}
}
I am not sure how I can get jQuery to print out any useful error messages. Currently when I try to debug the jQuery code using Chrome console it shows an empty xhr.responseText, nothing in "err" object and "status" set to "error" which as you see is not quite helpful.
One more thing that I have tried is to run the following code directly from the console:
$.ajax({
type: 'POST',
url: 'api/RecordUser',
data: {"Email":"email#address.com"},
dataType: 'json',
success: function (useremail) {
console.log(useremail);
},
error: function (xhr, status, err) {
console.log(xhr);
console.log(err);
console.log(status);
alert(err.Message);
},
complete: function (xhr, status) {
if (status === 'error' || !xhr.responseText) {
alert("Error");
}
else {
var data = xhr.responseText;
alert(data);
}
}
});
i.e. using the same script without actually clicking on the button and submitting the form. Surprisingly, this comes back with the right response and I can see my data printed out in console. For me this atleast means that my Web API controller is working fine but leaves me with no clue as to why it is not working on clicking the button or submitting the form and goes into "error" instead of "success".
I have failed to find any errors in my approach and would be glad if someone could help me in getting a response back when the form is posted.
As suggested by Alnitak, I was using complete callback along with success and error ones. Removing complete from my code fixed the issue.
Thanks to Alnitak.
I am use $.ajaxSetup to use a global authorization method, and global error handling in my site. I would like to pass a callback function into the global error method so I can call the function whenever I need to in the global error handler. Here is my $.ajaxSetup:
$.ajaxSetup({
global: false,
// type: "POST",
beforeSend: function (xhr) {
//The string needs to be turned into 'this.pasToken'
//if not us, don't include
if(app.cookieAuth)
xhr.setRequestHeader("Authorization", _this.pasToken);
},
statusCode: {
401: function(){
//Redirect to the login window if the user is unauthorized
window.location.href = app.loginUrl;
},
//This is where I need help
403: function(error, callback){
//Show an error message if permission isn't granted
callback(error);
alert(JSON.parse(error.responseText)['Message']);
}
}
});
Note the 403: status code. I am trying to pass in a callback function, but I don't know how to do it from the individual ajax calls. Anyone have an idea?
The easiest solution; define your own property for ajax options.
$.ajaxSetup({
statusCode: {
403: function(error, callback){
this.callback403(error);
}
}
});
$.ajax({
callback403: function () {}
});
Note, if you change the context option of the ajax request, this may not work.
I am not sure if this is what you are looking for:
$.ajax({
statusCode: {
404: function() {
alert("page not found");
}
}
});