Ajax- Why do I get an error function instead of success? - javascript

I don't understand why is my code running the error function instead of success. I keep getting this from my console.log
Object {readyState: 0, getResponseHeader: function, getAllResponseHeaders: function, setRequestHeader: function, overrideMimeType: function…}
I could not think of any reason why won't it execute my logic so I tried putting a redirect in my error function and this is what I get
Object {readyState: 0, getResponseHeader: function, getAllResponseHeaders: function, setRequestHeader: function, overrideMimeType: function…}
Basically the same thing happened so as of now I don't really have an idea as to what my problem is after editing the windows to window.
This is my code in js
function login(){
var username = document.getElementById("userID").value;
var password = document.getElementById("Password").value;
var postData = { "userID": username, "Password": password };
var postJSON = JSON.stringify(postData);
$.ajax({
url: "http://localhost:3000/api/login", // server url
type: "POST", //POST or GET
contentType: "application/json",
data: postJSON, // data to send in ajax format or querystring format
datatype: "JSON",
success: function(response) {
alert('success');
console.log(response);
window.location.replace("http://localhost/index.html");
},
error: function(response) {
alert('error');
console.log(response);
window.location.replace("http://localhost/index.html");
}
});
}
This is my html code. I am using onclick.
<input class="button" type="submit" id="submit" value="Log In" onclick="return login()"/>
So exactly what went wrong in my code? I am trying to call my login api (localhost:3000/api/login) through ajax with post which would then check mongodb for correct entries and output Login Success which then redirect to another page if input is correct and stay on the same page if input is wrong by giving output "Invalid Login ID or Password".
UPDATE:
Server Side Code
var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost:27017/myproject';
var authenticate = function(db, req, callback){
var cursor = db.collection('LoginID').find({"_id" : req.body.userID,
"Password" : req.body.Password
}).count(function(err,doc){
if(err) return callback(err);
if(doc == 0){
console.log('Invalid Login ID or Password');
return callback(null, doc);
} else {
console.log('Login Success');
return callback(null, doc);
}
});
}
module.exports = {
postCollection : function(req,res){
var username = req.body.userID;
var Password = req.body.Password;
//var createdDate = "<b>" + day + "/" + month + "/" + year + "</b>"
MongoClient.connect(url, function(err, db) {
//assert.equal(null, err);
if(err) {
res.send(err);
res.end();
}
authenticate(db, req, function(err,doc) {
if(err)
res.send(err);
else{
if(!doc){
res.send( ' Invalid Login ID or Password ' );
res.end();
} else {
res.send("Login success")
res.end();
}
}
db.close();
});
});
}
}

If I remember correctly, the success callback is only called if the HTTP return code is 2xx.
If you send back a redirection, it is considered as an error.
The documentation mentions it:
If the request is successful, the status
code functions take the same parameters as the success callback; if
it results in an error (including 3xx redirect), they take the same
parameters as the error callback.
From http://api.jquery.com/jquery.ajax/, statusCode section.
Moreover, you have to be careful: if an AJAX request receives a 302 response, it won't do a redirection: that is the user agent of your web browser (classic navigation) that does that automatically, but for XHR/AJAX, you have to implement it.

Related

why success function is never called and how can i fix it?

when i try and do the post, the data is send and the server receives it but the success function is never called. The connection appears in the network inspector tab of chrome as stalled and, a warning: connection is not finished yet.
script:
var modif = {
CRN: $("#DIAS").parent().parent().parent().children()[0].children[0].innerText,
DIAS: $("#DIAS").val(),
start_hr: $("#STRHR").val(),
end_hr: $("#ENDHR").val(),
title: $("#TITLE").val()
}
$.ajax({
url: '/cmanager/edit',
dataType: 'text',
type: 'POST',
data: modif,
success: function (order) {
alert("functiono!");
},
error: function(jqXHR, textStatus, errorThrown) {
alert("Error, status = " + textStatus + ", " +
"error thrown: " + errorThrown
);
server:
app.post("/cmanager/edit",function (req, res) {
var CRN = req.body.CRN;
var DIAS = req.body.DIAS;
var start_hr = req.body.start_hr;
var end_hr = req.body.end_hr;
var title = req.body.title;
console.log(CRN);
console.log(DIAS);
console.log(start_hr);
console.log(end_hr);
console.log(title);
var usrq = "update section natural join class set DIAS = '"+DIAS+"', start_hr = '"+start_hr+"', end_hr = '"+end_hr+"', title = '"+title+"' where CRN = '"+CRN+"';";
connection.query(usrq, function (error, results, fields) {
if (error)
console.log(error.code);
else
try {
console.log("hello");
} catch (error) {
console.log("bad ifo by client");
}
});
})
Nowhere in your server are you actually sending any data back to the client.
In your server, you need to call res.end() at a minimum. It looks to me what you actually want is res.sendStatus(204);.
Also note that you are wide open to SQL injection attacks, and you will be hacked if you haven't been already. Always use parameterized queries to avoid this problem entirely.

Jquery Initiated Download Returning 'Failed: Network Error'

I'm using a JQuery AJAX request that will trigger a download upon its completion.
CODE:
$('.getPDF').click(function(){
var filepath = 'localhost:3000/pdf/formula-' + this.id + '.pdf';
$.ajax({
url: '/formulas/'+ this.id +'/pdf',
type: 'POST',
success: downloadFile(filepath)
});
function downloadFile (path) {
var link = document.createElement('a');
link.href = path;
$(link).attr("download", true);
link.click();
}
});
This returns the following error in Chrome:
Failed - Network Error
with nothing else showing up in the console. The download does not work in Firefox or IE either.
I've done a console.log(filepath) in success, and the route it returns shows the correct file when I paste it into the browser-bar as a URL.
The HTML generating the AJAX Request looks like this:
<a class="pure-button button-success getPDF" id="59ac514a52c93e4aa862fadd">Generate PDF </a>
If it's relevant, the server side code generically looks like this:
router.post('/formulas/:id/pdf', function(req, res){
var db = req.db.collection('users');
var id = new ObjectID(req.params.id);
var pointer = {"formulas.$": 1, "_id": 0};
db.aggregate([
{$match: {"formulas.f_id": id}},
{$unwind: "$formulas"},
{$match: {"formulas.f_id": id}},
{$project : {"formulas": 1, "_id": 0}}
]).toArray(function(e, doc){
if (e) {
throw e;
} else {
var html = null;
ejs.renderFile('./views/pdf.ejs', {
project: doc[0].formulas
}, function(err, results){
if (err) {
console.log(err);
}
html = results;
});
var options = { format: 'Letter' };
var path = 'public/pdf/formula-' + req.params.id + '.pdf';
pdf.create(html, options).toFile(path, function(err, results) {
if (err) {
return console.log(err);
}
if (results) {
res.end();
}
});
}
});
});
The Ajax success callback has to be a function...
The first argument can be named as you wish... But will be filled with the Ajax response.
So the response is overwriting your filepath variable...
To avoid this, call downloadFile within a callback function.
And just ignore the response if you don't need it. ;)
success: function(response){
downloadFile(filepath);
}

ParseError: 'bad or missing username'

So I have some cloud code I am trying to write to like a post.
My database is setup that users have a likedPosts array, which has object id's of all the posts that the user liked. Users also have a column coins, that should get incremented when users like their posts.
The post object has a likes column which is an integer that gets incremented with each like, and the post object also has a posterId column, which is the object id of the user that posted it.
Here is my function right now (I am not very good at javascript and cloud code, so if there is something horribly wrong, I'm sorry)
Parse.Cloud.define("likePost", function(request, response) {
Parse.Cloud.useMasterKey();
var senderId = request.params.senderId;
var postId = request.params.postId;
var post = new Parse.Object ({objectId: postId});
var posterId = post.posterId
var poster = new Parse.User ({objectId: posterId});
var sender = new Parse.User ({objectId: senderId});
sender.add("likedPosts", postId);
poster.increment("coins");
post.increment("likes");
poster.save(null, {useMasterKey:true, success:
function(poster) {
console.log("Successfully saved poster");
}, error: function(poster, error) {
console.error("Error saving poster: " + error.message);
response.error(error);
}
});
post.save(null,{useMasterKey:true, success:
function(post) {
console.log("Successfully saved post");
}, error: function(post, error) {
console.error("Error saving post: " + error.message);
response.error(error);
}
});
sender.save(null, {useMasterKey:true, success:
function(sender) {
console.log("Successfully saved sender");
}, error: function(sender, error) {
console.error("Error saving sender: " + error.message);
response.error(error);
}
});
response.success();
});
I call the function from swift like so:
PFCloud.callFunction(inBackground: "likePost", withParameters: ["senderId" : PFUser.current()!.objectId!, " postId": postObject!.objectId!], block: { (result, error) in
if (error != nil) {
print(error!)
} else {
print("success liking")
}
})
In my logs, however, I get the following error:
2017-06-21T21:47:59.499Z - Failed running cloud function likePost for user R4d8Zrcdhw with:
Input: {"senderId":"R4d8Zrcdhw"," postId":"XXbu55PdpR"}
Error: {"code":141,"message":{"code":200,"message":"bad or missing username"}}
2017-06-21T21:47:59.492Z - bad or missing username
My guess is that the request is missing a header to define the content-type. I've seen Parse return the "bad or missing username" error via the Parse REST API if the Swift URLSession was using an incorrect content-type header.
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
or
Parse.Cloud.httpRequest({
url: 'http://www.example.com/',
headers: {
'Content-Type': 'application/json;charset=utf-8'
}
})

RESTful login using ajax and node.js

I'm struggling with a rather simple approach to login to a server and later on to ensure that I'm still logged in, I'm sending a GET request to receive my user name. I'm using a little node.js server and a single page object using JQuery.
// prints User name to the console if logged in
function getUserName() {
$.ajax({
url: "http://localhost:4730/login",
type: "GET",
dataType: "json",
success: function (resJson) {
$.each(resJson, function (i, userName) {
console.log(userName);
});
},
error: function (xhr, status) {
console.log("Sorry, there was a problem!");
}
});
}
// login a known user
function login(name, password) {
var userData = {
name: name,
password: password
};
$.ajax({
url: "http://localhost:4730/login",
type: "POST",
dataType: "json",
data: userData,
error: function (xhr, status) {
console.log("Sorry, there was a problem!");
},
complete: function (xhr, status) {
console.log(xhr);
}
});
}
My server (node.js) is generating a dummy user id and checks this one when the next GET request arrives.
// Checks if the user is logged in and returns its name or an empty string
app.get('/login', function (req, res) {
if (typeof (req.session.user_id) == "number") {
res.json(users[req.session.user_id].name);
return;
}
res.json("");
});
// Check if the user exists and if the password is correct
app.post('/login', function (req, res) {
var post = req.body;
var user = findUser(post.name);
if( !!user && post.password == user.password)
{
req.session.user_id = user.id;
res.json(true);
return;
}
res.json(false);
});
My user is already registered and the login request returns successfully. But after logged in, my GET request to getUserName returns an empty string. What I don't get is where is the session.user_id set? Doesn't the client has to now it?
I have already seen couple of solutions by using passport, etc but I would like to understand the basic of the session/user id handling.
Thanks a lot for your help
Here:
var post = req.body; // the request body with username & password.
var user = findUser(post.name); // you are extracting the username
if( !!user && post.password == user.password)
//---------------------------^^^^^^^^^^^^^-----this isn't available in it.
In your var post you have all the posted request body, which has name & password.
In your var user you are extracting the name out of posted values.
Now in your if condition i don't think user.password is available.
Either make sure you would return the object from findUser(post.name) or change it to: post.password != ""

Node.js Page Redirect on AJAX login? With a function call after redirect?

The '/stories' page is user-specific and requires valid login credentials.
Validation is accounted for with node, server-side, and properly logs before the redirect, but does not redirect to the stories page..
This seems to be because "You can't make a redirection after an AJAX. You need to do it yourself in Javascript", but the code in the first answer to this question seems somewhat incomplete..for the succcess call..
Also, how can a subsequent function (refreshStories) be called on success after the redirect?
Here's the AJAX:
if (loginUsername.length != 0) {
console.log('there is a login: ' + loginUsername);
// make an ajax call
$.ajax({
dataType: 'json',
data: AjaxLoginData,
type: 'post',
url:"http://localhost:4200/api/v1/users",
success: (data, textStatus, jqXHR) ->
if typeof data.redirect == 'string'
window.location = data.redirect
success: refreshStories,
error: foundError
});
Node.js + Express4
router.route('/users')
// log in a user (accessed at POST http://localhost:4200/api/v1/users)
.post(function(req, res) {
var username = req.body.loginUsername;
var password = req.body.loginPassword;
authenticateUser(username, password, function(err, user){
console.log('authenticate user..');
if (user) {
console.log('yes user');
// subsequent requests will know the user is logged in
req.session.username = user.username;
console.log('set session username to: ' + req.session.username);
// res.redirect('/stories');
res.send({redirect: '/stories'});
console.log('user logged in .. redirect to stories');
} else {
console.log('user authentication badCredentials error..');
res.render('index', {badCredentials: true});
}
});
});
Try this
if (loginUsername.length != 0) {
console.log('there is a login: ' + loginUsername);
// make an ajax call
$.ajax({
dataType: 'json',
data: AjaxLoginData,
type: 'post',
url:"http://localhost:4200/api/v1/users",
success: (data, textStatus, jqXHR) ->
if (typeof data.redirect == 'string')
window.location.replace(window.location.protocol + "//" + window.location.host + data.redirect);
error: foundError
});
window.location.replace(...) will best simulate an HTTP redirect
How to redirect to another webpage in JavaScript/jQuery?
For your 'refreshStories' stuff, you should just refresh Stories when you go to '/stories'

Categories

Resources