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>

Problem courtesy of: peter.petrov

Solution

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>

Solution courtesy of: peter.petrov

Discussion

This does what you're looking for: https://github.com/braitsch/node-login

I'd recommend grabbing that from git and looking through it. You could even use it as a template. Pretty good stuff, and when you want to see the client side of things you can just look at the scripts associated with the login page.

example here: http://node-login.braitsch.io/

Discussion courtesy of: BRogers

This recipe can be found in it's original form on Stack Over Flow .

我来评几句
登录后评论

已发表评论数()

相关站点

+订阅
热门文章