106 votes

nodejs - le premier argument doit être une chaîne ou un tampon - lors de l'utilisation de response.write avec http.request

J'essaie simplement de créer un serveur de nœuds qui affiche le statut HTTP d'une URL donnée.

Lorsque j'essaie de vider la réponse avec res.write, j'obtiens l'erreur suivante : throw new TypeError('first argument must be a string or Buffer') ;

Mais si je les remplace par console.log, tout va bien (mais je dois les écrire dans le navigateur et non dans la console).

Le code est le suivant

var server = http.createServer(function (req, res) {
    res.writeHead(200, {"Content-Type": "text/plain"});

    request({
        uri: 'http://www.google.com',
        method: 'GET',
        maxRedirects:3
    }, function(error, response, body) {
        if (!error) {
            res.write(response.statusCode);
        } else {
            //response.end(error);
            res.write(error);
        }
    });     

    res.end();
});
server.listen(9999);

Je pense que je devrais ajouter une fonction de rappel quelque part, mais je suis assez confus et toute aide est appréciée.

55voto

Alex Mills Points 635

J'obtiens ce message d'erreur et il mentionne options.body

J'avais ceci à l'origine

request.post({
    url: apiServerBaseUrl + '/v1/verify',
    body: {
        email: req.user.email
    }
});

Je l'ai changé en ceci :

request.post({
    url: apiServerBaseUrl + '/v1/verify',
    body: JSON.stringify({
        email: req.user.email
    })
});

et il semble fonctionner maintenant sans le message d'erreur ... semble être un bug cependant.

Je pense que c'est la manière la plus officielle de procéder :

 request.post({
        url: apiServerBaseUrl + '/v1/verify',
        json: true,
        body: {
            email: req.user.email
        }
    });

54voto

loganfsmyth Points 25483

response.statusCode est un nombre, par exemple response.statusCode === 200 pas '200' . Comme le dit le message d'erreur, write s'attend à ce qu'un string o Buffer vous devez donc le convertir.

res.write(response.statusCode.toString());

Vous avez également raison en ce qui concerne votre commentaire sur le callback. res.end(); doit être à l'intérieur du callback, juste en dessous de votre write appels.

33voto

Gaurav Agarwal Points 2202

La demande prend une méthode de rappel, c'est asynchrone ! Je suppose donc qu'au moment où la méthode de rappel est exécutée, l'application res.end() pourrait être appelé. Essayez de fermer la demande dans le callback.

14voto

freakish Points 20067

Il est évident que vous essayez d'envoyer quelque chose qui n'est pas une chaîne ou un tampon :) Cela fonctionne avec la console, car la console accepte tout. Exemple simple :

var obj = { test : "test" };
console.log( obj ); // works
res.write( obj ); // fails

Une façon de convertir n'importe quoi en chaîne de caractères est de le faire :

res.write( "" + obj );

lorsque vous essayez d'envoyer quelque chose. L'autre moyen est d'appeler .toString() méthode :

res.write( obj.toString( ) );

Notez que cela ne correspond peut-être pas à ce que vous recherchez. Vous devez toujours passer des chaînes ou des tampons à la fonction .write sans de telles astuces.

En passant, je suppose que request est une opération asynchrone. Si c'est le cas, alors res.end(); sera appelé avant toute écriture, c'est-à-dire que toute écriture échouera de toute façon (parce que la connexion sera fermée à ce moment-là). Déplacez cette ligne dans le gestionnaire :

request({
    uri: 'http://www.google.com',
    method: 'GET',
    maxRedirects:3
}, function(error, response, body) {
    if (!error) {
        res.write(response.statusCode);
    } else {
        //response.end(error);
        res.write(error);
    }
    res.end( );
});

1voto

Mohsin Muzawar Points 700

Si vous voulez écrire un objet JSON dans la réponse, changez le type de contenu de l'en-tête en application/json.

response.writeHead(200, {"Content-Type": "application/json"});
var d = new Date(parseURL.query.iso);
var postData = {
    "hour" : d.getHours(),
    "minute" : d.getMinutes(),
    "second" : d.getSeconds()
}
response.write(postData)
response.end();

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