web-dev-qa-db-fra.com

Envoi/réception Ajax de base avec node.js

J'essaie donc de créer un serveur node.js très basique qui, avec une demande de chaîne, en sélectionne une au hasard dans un tableau et renvoie la chaîne sélectionnée. Malheureusement, je rencontre quelques problèmes.

Voici le front end:

function newGame()
{
   guessCnt=0;
   guess="";
   server();
   displayHash();
   displayGuessStr();
   displayGuessCnt();
}

function server()
{
   xmlhttp = new XMLHttpRequest();

   xmlhttp.open("GET","server.js", true);
   xmlhttp.send();

   string=xmlhttp.responseText;
}

Cela devrait envoyer la demande à server.js:

var http = require('http');

var choices=["hello world", "goodbye world"];

console.log("server initialized");

http.createServer(function(request, response)
{
    console.log("request recieved");
    var string = choices[Math.floor(Math.random()*choices.length)];
    console.log("string '" + string + "' chosen");
    response.on(string);
    console.log("string sent");
}).listen(8001);

Donc, clairement, il y a plusieurs choses qui ne vont pas ici:

  1. J'ai l'impression que la façon dont je "connecte" ces deux fichiers n'est pas correcte, à la fois dans la méthode xmlhttp.open et dans l'utilisation de response.on pour renvoyer la chaîne au début.

  2. Je suis un peu confus avec la façon dont j'appelle cette page sur localhost. Le serveur frontal est nommé index.html et le serveur envoie le message à 8001. Quelle adresse dois-je accéder à localhost pour accéder à la page html initiale après avoir initialisé server.js? Devrais-je le changer pour .listen(index.html) ou quelque chose comme ça?

  3. y a-t-il d'autres problèmes évidents avec la façon dont j'implémente cela (en utilisant .responsetext etc.)

(désolé pour le long post contenant plusieurs questions, mais les divers tutoriels et la source de node.js supposent tous que l'utilisateur comprend déjà ces choses.)

54
Daniel Nill
  1. Votre demande doit être adressée au serveur, PAS au fichier server.js qui l’instancie. Ainsi, la demande devrait ressembler à ceci: xmlhttp.open("GET","http://localhost:8001/", true); En outre, vous essayez de servir les demandes frontales (index.html) ET de servir AJAX au même URI. Pour ce faire, vous devrez introduire dans votre fichier server.js une logique qui différenciera vos demandes AJAX d'une demande d'accès http normale. Pour ce faire, vous devrez soit introduire les données GET/POST (par exemple, appeler http://localhost:8001/?getstring=true), soit utiliser un chemin différent pour vos demandes AJAX (par exemple, appeler http://localhost:8001/getstring). Sur le serveur, vous devrez alors examiner l’objet request pour déterminer ce qu’il faut écrire dans la réponse. Pour cette dernière option, vous devez utiliser le module 'url' pour analyser la requête.

  2. Vous appelez correctement listen() mais vous écrivez de manière incorrecte la réponse. Tout d'abord, si vous souhaitez servir index.html lors de la navigation vers http: // localhost: 8001 / , vous devez écrire le contenu du fichier dans la réponse à l'aide de response.write() ou response.end(). Tout d'abord, vous devez inclure fs=require('fs') pour avoir accès au système de fichiers. Ensuite, vous devez réellement servir le fichier.

  3. XMLHttpRequest a besoin d'une fonction de rappel spécifiée si vous l'utilisez de manière asynchrone (troisième paramètre = true, comme vous l'avez fait) ET souhaitez faire quelque chose avec la réponse. Comme vous l'avez maintenant, string sera undefined (ou peut-être null), car cette ligne s'exécutera avant la fin de la demande AJAX (c'est-à-dire, le responseText est encore vide). Si vous l'utilisez de manière synchrone (troisième paramètre = false), vous pouvez écrire le code en ligne comme vous l'avez fait. Ce n'est pas recommandé car cela verrouille le navigateur pendant la requête. L'opération asynchrone est généralement utilisée avec la fonction onreadystatechange, qui peut gérer la réponse une fois qu'elle est terminée. Vous devez apprendre les bases de XMLHttpRequest. Démarrer ici.

Voici une implémentation simple qui intègre tout ce qui précède:

server.js:

var http = require('http'),
      fs = require('fs'),
     url = require('url'),
 choices = ["hello world", "goodbye world"];

http.createServer(function(request, response){
    var path = url.parse(request.url).pathname;
    if(path=="/getstring"){
        console.log("request recieved");
        var string = choices[Math.floor(Math.random()*choices.length)];
        console.log("string '" + string + "' chosen");
        response.writeHead(200, {"Content-Type": "text/plain"});
        response.end(string);
        console.log("string sent");
    }else{
        fs.readFile('./index.html', function(err, file) {  
            if(err) {  
                // write an error response or nothing here  
                return;  
            }  
            response.writeHead(200, { 'Content-Type': 'text/html' });  
            response.end(file, "utf-8");  
        });
    }
}).listen(8001);
console.log("server initialized");

frontend (partie de index.html):

function newGame()
{
   guessCnt=0;
   guess="";
   server();
   displayHash();
   displayGuessStr();
   displayGuessCnt();
}

function server()
{
   xmlhttp = new XMLHttpRequest();
   xmlhttp.open("GET","http://localhost:8001/getstring", true);
   xmlhttp.onreadystatechange=function(){
         if (xmlhttp.readyState==4 && xmlhttp.status==200){
           string=xmlhttp.responseText;
         }
   }
   xmlhttp.send();
}

Vous devrez être à l'aise avec AJAX. Utilisez le centre de formation de mozilla pour en savoir plus sur XMLHttpRequest. Une fois que vous pouvez utiliser l’objet XHR de base, vous souhaiterez probablement utiliser une bonne bibliothèque AJAX au lieu d’écrire manuellement des requêtes multi-navigateurs AJAX (par exemple, dans IE vous devrez utiliser un ActiveXObject au lieu de XHR). Le AJAX dans jQuery est excellent, mais si vous n'avez pas besoin de tout le reste jQuery offre, trouvez une bonne bibliothèque AJAX ici: http://microjs.com/ . Vous aurez également besoin de vous familiariser avec les documents node.js, trouvés ici. Cherchez http://google.com pour trouver de bons didacticiels sur les serveurs node.js et les serveurs de fichiers statiques. http://nodetuts.com est un bon point de départ.

UPDATE: J'ai changé response.sendHeader() à la nouvelle response.writeHead() dans le code ci-dessus !!!

60
ampersand

Express rend ce genre de choses vraiment intuitif. La syntaxe ressemble à celle ci-dessous:

var app = require('express').createServer();
app.get("/string", function(req, res) {
    var strings = ["rad", "bla", "ska"]
    var n = Math.floor(Math.random() * strings.length)
    res.send(strings[n])
})
app.listen(8001)

http://expressjs.com/guide.html

Si vous utilisez jQuery côté client, vous pouvez faire quelque chose comme ceci:

$.get("/string", function(string) {
    alert(string)
})
29
Jamund Ferguson

Je faisais face à l'erreur suivante avec code (nodejs 0.10.13), fourni par esperluette:

Origin n'est pas autorisé par access-control-allow-Origin

Le problème était résolu changeant

response.writeHead(200, {"Content-Type": "text/plain"});

à 

response.writeHead(200, {
                 'Content-Type': 'text/html',
                 'Access-Control-Allow-Origin' : '*'});
5
theme

Voici un exemple pleinement fonctionnel de ce que vous essayez d'accomplir. J'ai créé l'exemple à l'intérieur d'hyperdev plutôt que de jsFiddle afin que vous puissiez voir le code côté serveur et le code côté client. 

Voir le code: https://hyperdev.com/#!/project/destiny-authorization

Voir l'application de travail: https://destiny-authorization.hyperdev.space/

Ce code crée un gestionnaire pour une demande get qui renvoie une chaîne aléatoire:

app.get("/string", function(req, res) {
    var strings = ["string1", "string2", "string3"]
    var n = Math.floor(Math.random() * strings.length)
    res.send(strings[n])
});

Ce code jQuery fait ensuite la demande ajax et reçoit la chaîne aléatoire du serveur.

$.get("/string", function(string) {
  $('#txtString').val(string);
});

Notez que cet exemple est basé sur le code de la réponse de Jamund Ferguson, donc si vous trouvez cela utile, veillez également à le faire revenir au vote. Je pensais juste que cet exemple vous aiderait à voir comment tout s'emboîtait.

0
Nick Painter