peter.petrov peter.petrov - 9 days ago 7
Javascript Question

Express POST - Returned JSON is treated as invalid by JQuery

I am trying to write a small authentication service using Express and Node.

I did a search on SO and don't seem to find my answer
even though there're many similar questions but no
definitive answer really.

I tried many variations of my server side code but
seems I am still missing something.

The POST call is made from an HTML page
with some JQuery code (ajax call).

I enter the post() method in Express but when
it returns response to the HTML page, always the ajax
error handler is executed, never the success handler.

My JSON which I return seems valid to me.
I tried calling send and json on the
response object but nothing really works.

What am I missing?

Any help would be greatly appreciated.
Thanks in advance.

var mod = require('express');

var auth = require('./login_module.js'); // my module

var express = require('express');
var app = express();

app.use(express.bodyParser());

app.post('/login', function(request, response) {

console.log("post method called");

var credentials = request.body;
console.log("credentials = " + credentials);
console.log(credentials);

auth.authenticate(credentials.username, credentials.password, function(result){
console.log("Authentication Result: " + result);
var code = result === 1 ? 200 : 401;
console.log("Response Code: " + code);
var res = {
data : "Response Code: " + code
};
console.log(JSON.stringify(res));

// So far I am good!

response.statusCode = code;
response.json(res);

// Response is now sent
// but not recognized as
// valid JSON in the client.
console.log("response sent");
});

});

app.listen(10101);


JQuery call.

<script type="text/javascript">
$(document).ready(function(){
$( "#btn" ).click(function(){
alert('calling now!');
var obj = {
username: $('#usrn').val(),
password: $('#pwd').val()
};
$.ajax({
type: "POST",
url: 'http://localhost:10101/login',
data: obj,
success: function (data, textStatus, jqXHR){
alert('got response back!');
if ("200" === textStatus){
$('#status').text('Login succeeded!');
}else if ("401" === textStatus){
$('#status').text('Login failed!');
}else{
$('#status').text('Invalid status received: ' + textStatus);
}
},
error : function(jqXHR, textStatus, errorThrown){
alert("Error when getting response.");
},

dataType: 'json'
});
})
});
</script>

Answer

As adeneo pointed out the key was to serve the html page over
http and not over file protocol. The rest was just some tuning
of various details about the Ajax jQuery call.

Server-side code:

var mod = require('express');

var auth = require('./acct_module.js');
var fs = require('fs');

var express = require('express');
var app = express();

app.use(express.bodyParser());

app.post('/login', function(request, response) {

   console.log("POST called - try to login against the MongoDB.");

   var credentials = request.body;
   console.log("credentials = " + credentials);
   console.log(credentials.username);
   console.log(credentials.password);

   auth.authenticate(credentials.username, credentials.password, function(result){
        console.log("Authentication Result: " + result);
        var code = result === 1 ? 200 : 401;
        var message = result === 1 ? "Login succeeded!" : "Login failed!";
        console.log("Response Code: " + code);
        var res = {
            message: message,
            code : code
        };

        console.log(JSON.stringify(res));

        response.statusCode = code;

        response.json(res);

        console.log("POST response sent.");
   });

});

app.get('/login', function(request, response){
    console.log("GET called - send back the HTML file.");
    fs.readFile('login.html', function (err, data) {
        if (err) {
            response.writeHead(500, {'Content-Type': 'text/html'});
            response.write("Request failed.");
            response.end();
            return;
        }
        response.writeHead(200, {'Content-Type': 'text/html'});
        response.write(data);
        response.end();

        console.log("GET response sent.");
    });
});

app.listen(10101);



Login page login.html:

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>

    <script type="text/javascript">
        $(document).ready(function(){
            $( "#btn" ).click(function(){
                  // alert('Now calling the auth manager!');
                  var obj = {
                    username: $('#usrn').val(),
                    password: $('#pwd').val()
                  };
                $.ajax({
                    type: "POST",
                    url: 'http://localhost:10101/login',
                    data: obj,
                    success: function (data, textStatus, jqXHR){
                        // alert('success called!');
                        var res = JSON.parse(jqXHR.responseText);
                        $('#status_message').html(res.message);
                        $('#status_code').html(res.code);
                    },
                    error : function(jqXHR, textStatus, errorThrown){
                        // alert('error called!');
                        var res = JSON.parse(jqXHR.responseText);
                        $('#status_message').html(res.message);
                        $('#status_code').html(res.code);
                    },
                    dataType: 'json'
                });
            })
        });
    </script>

</head>
<body>
    <input type="text" id="usrn" name="usrn"/><br>
    <input type="password" id="pwd" name="pwd"/><br>
    <input type="button" id="btn" name="btn" value="LOGIN!"/><br><br>
    <div id="status_message" name="status_message"></div><br>
    <div id="status_code" name="status_code"></div><br>
</body>
</html>
Comments