70 votes

comment utiliser les appels ajax de jQuery avec node.js

Ceci est similaire à Stream de données avec Node.js mais je ne pense pas que cette question ait reçu une réponse suffisante.

J'essaie d'utiliser un appel ajax jQuery (get, load, getJSON) pour transférer des données entre une page et un serveur node.js. Je peux cliquer sur l'adresse depuis mon navigateur et voir "Hello World !", mais lorsque j'essaie de le faire depuis ma page, cela échoue et je n'obtiens aucune réponse. J'ai configuré une page de test simple et un exemple de "Hello World" pour tester cela :

<!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>

et

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);

86voto

yojimbo87 Points 27744

Si votre page de test simple est située sur un autre protocole/domaine/port que votre exemple hello world node.js, vous effectuez des requêtes inter-domaines et vous violez politique de même origine Par conséquent, vos appels jQuery ajax (get et load) échouent en silence. Pour que cela fonctionne sur plusieurs domaines, vous devez utiliser JSONP format basé sur la technologie. Par exemple, le code node.js :

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);

et JavaScript/jQuery côté client :

$(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);
        }
    });
});

Il existe également d'autres moyens de faire fonctionner cette fonction, par exemple en configurant reverse proxy ou construire votre application web entièrement avec un framework comme express .

8voto

Michael Dausmann Points 985

Merci à yojimbo pour sa réponse. Pour compléter son exemple, j'ai voulu utiliser la méthode jquery $.getJSON qui place un callback aléatoire dans la chaîne de requête et je voulais aussi analyser cela dans Node.js. Je voulais aussi passer un objet en retour et utiliser la fonction stringify.

Voici mon code côté client.

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

C'est mon Node.js côté serveur.

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);

3voto

Adrien Points 5142

Je suppose que votre page html est hébergée sur un port différent. Même politique d'origine nécessite dans la plupart des navigateurs que le fichier chargé soit sur le même port que le fichier de chargement.

1voto

Utilisez quelque chose comme ce qui suit du côté du serveur :

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)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X