Ajax post response from express js keeps throwing error

Problem

I am having a real hard time standing up bidirectional data transfer from a html page to my node.js application and then back to the html page.

I'm pretty sure I'm all over the correct solution, but I'm just not getting it to work.

I'm using the following for my node.js application:

var express = require('/usr/lib/node_modules/express');
var app = express();

app.use(function(err, req, res, next){
  console.error(err.stack);
  res.send(500, 'Something broke!');
});

app.use(express.bodyParser());

app.post('/namegame', function(req, res)
    {
        console.log('Got request name: ' + req.body.name);
        setTimeout(function() 
        { 
            var newName = "New Name-O";
            res.send({name: newName});
        }, 2000);
    }
);

app.listen(8088, function() { console.log("Server is up and running");  });

The following is my html page:

<html> 
<head> 
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.js"></script> 

    <script type="text/javascript"> 
        // wait for the DOM to be loaded 
        $(document).ready(function() 
        {
            alert("Got here!");

            function DisplayName(response)
            {
                alert(response.newName);
            }

            $("#NameGameIt").click(function(event)
            {
                alert("How about now?");
                //event.PreventDefault();
                var nameSubmitted = document.getElementById("name");
                //var nameSubmitted = "help!!";

                alert("Name: " + nameSubmitted.value);

                $.ajax({
                    type:       "POST",
                    url:        "http://127.0.0.1:8088/namegame",
                    data:       {name: nameSubmitted.value},
                    dataType:   "json",
                    timeout:    2500,
                    success:    function() { alert("???");},
                    error:      function(error1, error2, error3)
                    {   alert("error"); },
                    complete:   function(arg1, arg2, arg3)
                    {   alert("complete");  }
                });

            });

        });

    </script>

</head> 
<body>

<h1>Test form for Ajax</h1>
</br>

Name: <input type="text" id="name" name="name"></br>
<input type="button" value="NameGameIt" id="NameGameIt">
</form>

</body>
</html>

So, when I run the node application, the server comes up just fine. When I fire up the html page, I get the alert "Got here!" When I press the button "NameGameIt", I get the alert "How about now?" followed by the alert "Name: " + whatever name I entered. Once I click off that alert, the node application immediately sees the post and prints out the name to the console. Two seconds later when the node sends the response, the browser will go right into the error handler on the ajax post. The only useful data to come out in the error handler is that it is an "error" which isn't really useful.

So I know the message is getting to the node from the html page because it prints out the name that I sent and I know the html page is getting the message back from the node because it won't error out until the timeout on the node happens triggering the send. But, I have no idea why it keeps on sending me to the error handler instead of the success. I've stepped through all the way in the node code using node-inspector and it seems to be building the packet correctly with a 200 code for success and it calls .end inside .send after it's done making the packet so I don't think either of those things are biting me.

I'm about to go nuts! If anyone sees what I'm missing or has any new ideas on ways to gather more information, I would be very grateful for the help.

Problem courtesy of: Brian

Solution

Your code is perfectly fine, but you're almost certainly running into a cross-domain AJAX request issue. You might be opening this HTML file on the local filesystem and making requests that way, which is what is causing this problem.

To fix it, add app.use(express.static('public')); like so:

var express = require('/usr/lib/node_modules/express');
var app = express();

app.use(function(err, req, res, next){
  console.error(err.stack);
  res.send(500, 'Something broke!');
});

app.use(express.bodyParser());
app.use(express.static('public'));

app.post('/namegame', function(req, res)
    {
        console.log('Got request name: ' + req.body.name);
        setTimeout(function() 
        { 
            var newName = "New Name-O";
            res.send({name: newName});
        }, 2000);
    }
);

app.listen(8088, function() { console.log("Server is up and running");  });

and then place your html file in the 'public' folder. Once you launch your server, you can visit http://127.0.0.1:8088/file.html and your code will run fine.

Solution courtesy of: Benjamin

Discussion

There is currently no discussion for this recipe.

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