nodejs - il primo argomento deve essere una stringa o Buffer - quando si utilizza response.write con http.request


92

Sto semplicemente cercando di creare un server del nodo che restituisca lo stato HTTP di un determinato URL.

Quando provo a svuotare la risposta con res.write, ottengo l'errore: throw new TypeError ('il primo argomento deve essere una stringa o Buffer');

Ma se li sostituisco con console.log, va tutto bene (ma devo scriverli sul browser e non sulla console).

Il codice è

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

Credo che dovrei aggiungere una richiamata da qualche parte, ma piuttosto confuso e qualsiasi aiuto è apprezzato.

Risposte:


31

La richiesta accetta un metodo di callback, è asincrono! Quindi presumo che, nel momento in cui viene eseguito il callback, res.end()potrebbe essere chiamato. Prova a chiudere la richiesta all'interno della richiamata.


1
Lo ha fatto e ha anche aggiunto .toString. Grazie mille
umutm

Sembra che me ne sia dimenticato. L'ho appena fatto. Grazie.
umutm

1
@umutm Ci sono risposte più ben scritte ed elaborate, probabilmente dovresti accettarne una; rendendolo visibile a chiunque giunga a questa domanda.
Gaurav Agarwal

52

response.statusCodeè un numero, ad esempio response.statusCode === 200no '200'. Come dice il messaggio di errore, si writeaspetta un oggetto stringo Buffer, quindi è necessario convertirlo.

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

Hai anche ragione riguardo al tuo commento di richiamata. res.end();dovrebbe essere all'interno della richiamata, appena sotto le writechiamate.


Sì, quello ha funzionato. Come principiante di nodejs, non lo sapevo e grazie mille.
umutm

48

Ottengo questo messaggio di errore e menziona options.body

Inizialmente avevo questo

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

L'ho cambiato in questo:

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

e ora sembra funzionare senza il messaggio di errore ... sembra un bug però.

Penso che questo sia il modo più ufficiale per farlo:

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

4
Il tuo problema è diverso, per impostazione predefinita il corpo dovrebbe essere una stringa o un Buffer. Puoi anche cambiarlo (per essere serializzabile json) aggiungendo json: true alle opzioni. Ad esempio: request.post ({url: apiServerBaseUrl + '/ v1 / verify', body: {email: req.user.email}, json: true})
Nuno Tomas

2
Potresti usarlo per evitare di stringere javascript request.post({ url: apiServerBaseUrl + '/v1/verify', json: { email: req.user.email } }
bsorrentino

13

Ovviamente stai cercando di inviare qualcosa che non sia una stringa o un buffer. :) Funziona con la console, perché la console accetta qualsiasi cosa. Esempio semplice:

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

Un modo per convertire qualsiasi cosa in stringa è farlo:

res.write( "" + obj );

ogni volta che provi a inviare qualcosa. L'altro modo è chiamare il .toString()metodo:

res.write( obj.toString( ) );

Nota che potrebbe non essere ancora quello che stai cercando. Dovresti sempre passare stringhe / buffer .writesenza questi trucchi.

Come nota a margine: presumo che requestsia un'operazione asincrona. Se questo è il caso, res.end();verrà chiamato prima di qualsiasi scrittura, cioè qualsiasi scrittura fallirà comunque (perché la connessione verrà chiusa a quel punto). Sposta quella linea nel gestore:

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

Grazie mille per la risposta e le informazioni dettagliate. E sì, ho spostato il res.end nel gestore. Ho accettato @loganfsmyth com'era prima. Grazie ancora.
umutm

1

se si desidera scrivere un oggetto JSON nella risposta, modificare il tipo di contenuto dell'intestazione in 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();

1

E c'è un'altra possibilità (non in questo caso) quando si lavora con ajax (XMLhttpRequest), mentre si inviano le informazioni al client è necessario utilizzare res.send (responsetext) invece di res.end (responsetext)


1

Sebbene la domanda sia risolta, condividendo le conoscenze per chiarire il significato corretto dell'errore.

L'errore dice che il parametro necessario alla funzione di interruzione interessata non è nel formato richiesto, ovvero stringa o buffer

La soluzione è modificare il parametro in stringa

breakingFunction(JSON.stringify(offendingParameter), ... other params...);

o buffer

breakingFunction(BSON.serialize(offendingParameter), ... other params...);

0

Il primo argomento deve essere di tipo stringa o Buffer. Oggetto di tipo ricevuto

 at write_

Stavo ricevendo l'errore precedente mentre passavo i dati del corpo al modulo di richiesta.

Ho passato un altro parametro che è JSON: true e il suo funzionamento.

var option={
url:"https://myfirstwebsite/v1/appdata",
json:true,
body:{name:'xyz',age:30},
headers://my credential
}
rp(option)
.then((res)=>{
res.send({response:res});})
.catch((error)=>{
res.send({response:error});})
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.