简体   繁体   中英

how to use jQuery ajax calls with node.js

This is similar to Stream data with Node.js , but I don't feel that question was answered sufficiently.

I'm trying to use a jQuery ajax call (get, load, getJSON) to transfer data between a page and a node.js server. I can hit the address from my browser and see 'Hello World!", but when I try this from my page, it fails and shows that I get no response back. I setup a simple test page and hello world example to test this:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>get test</title> 
</head>
<body>
    <h1>Get Test</h1>
    <div id="test"></div>

    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.js"></script>
    <script>
        $(document).ready(function() {
            //alert($('h1').length);
            $('#test').load('http://192.168.1.103:8124/');
            //$.get('http://192.168.1.103:8124/', function(data) {                
            //  alert(data);
            //});
        });
    </script>
</body>
</html>

and

var http = require('http');

http.createServer(function (req, res) {
    console.log('request received');
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello World\n');
}).listen(8124);

If your simple test page is located on other protocol/domain/port than your hello world node.js example you are doing cross-domain requests and violating same origin policy therefore your jQuery ajax calls (get and load) are failing silently. To get this working cross-domain you should use JSONP based format. For example node.js code:

var http = require('http');

http.createServer(function (req, res) {
    console.log('request received');
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('_testcb(\'{"message": "Hello world!"}\')');
}).listen(8124);

and client side JavaScript/jQuery:

$(document).ready(function() {
    $.ajax({
        url: 'http://192.168.1.103:8124/',
        dataType: "jsonp",
        jsonpCallback: "_testcb",
        cache: false,
        timeout: 5000,
        success: function(data) {
            $("#test").append(data);
        },
        error: function(jqXHR, textStatus, errorThrown) {
            alert('error ' + textStatus + " " + errorThrown);
        }
    });
});

There are also other ways how to get this working, for example by setting up reverse proxy or build your web application entirely with framework like express .

Thanks to yojimbo for his answer. To add to his sample, I wanted to use the jquery method $.getJSON which puts a random callback in the query string so I also wanted to parse that out in the Node.js. I also wanted to pass an object back and use the stringify function.

This is my Client Side code.

$.getJSON("http://localhost:8124/dummy?action=dostuff&callback=?",
function(data){
  alert(data);
},
function(jqXHR, textStatus, errorThrown) {
    alert('error ' + textStatus + " " + errorThrown);
});

This is my Server side Node.js

var http = require('http');
var querystring = require('querystring');
var url = require('url');

http.createServer(function (req, res) {
    //grab the callback from the query string   
    var pquery = querystring.parse(url.parse(req.url).query);   
    var callback = (pquery.callback ? pquery.callback : '');

    //we probably want to send an object back in response to the request
    var returnObject = {message: "Hello World!"};
    var returnObjectString = JSON.stringify(returnObject);

    //push back the response including the callback shenanigans
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end(callback + '(\'' + returnObjectString + '\')');
}).listen(8124);

I suppose your html page is hosted on a different port. Same origin policy requires in most browsers that the loaded file be on the same port than the loading file.

Use something like the following on the server side:

http.createServer(function (request, response) {
    if (request.headers['x-requested-with'] == 'XMLHttpRequest') {
        // handle async request
        var u = url.parse(request.url, true); //not needed

        response.writeHead(200, {'content-type':'text/json'})
        response.end(JSON.stringify(some_array.slice(1, 10))) //send elements 1 to 10
    } else {
        // handle sync request (by server index.html)
        if (request.url == '/') {
            response.writeHead(200, {'content-type': 'text/html'})
            util.pump(fs.createReadStream('index.html'), response)
        } 
        else 
        {
            // 404 error
        }
    }
}).listen(31337)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM