nodejs - erstes Argument muss eine Zeichenfolge oder ein Puffer sein - bei Verwendung von response.write mit http.request

91

Ich versuche einfach, einen Knotenserver zu erstellen, der den HTTP-Status einer bestimmten URL ausgibt.

Wenn ich versuche, die Antwort mit res.write zu leeren, wird folgende Fehlermeldung angezeigt: throw new TypeError ('erstes Argument muss eine Zeichenfolge oder ein Puffer sein');

Aber wenn ich sie durch console.log ersetze, ist alles in Ordnung (aber ich muss sie in den Browser schreiben, nicht in die Konsole).

Der Code ist

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

Ich glaube, ich sollte irgendwo einen Rückruf hinzufügen, aber ziemlich verwirrt, und jede Hilfe wird geschätzt.

umutm
quelle

Antworten:

31

Die Anforderung verwendet eine Rückrufmethode, die asynchron ist! Ich gehe also davon aus, dass der Anruf zum Zeitpunkt der Ausführung des Rückrufs res.end()möglicherweise aufgerufen wird. Versuchen Sie, die Anforderung innerhalb des Rückrufs zu schließen.

Gaurav Agarwal
quelle
1
Hab das gemacht und auch .toString hinzugefügt. Vielen Dank.
Umutm
Scheint, als hätte ich es vergessen. Habe es gerade getan. Vielen Dank.
Umutm
1
@umutm Es gibt besser geschriebene und ausführlichere Antworten, Sie sollten wahrscheinlich eine davon akzeptieren. es für jeden sichtbar machen, der zu dieser Frage kommt.
Gaurav Agarwal
52

response.statusCodeist eine Zahl, zB response.statusCode === 200nicht '200'. Erwartet, wie in der Fehlermeldung angegeben, writeein stringoder BufferObjekt, müssen Sie es konvertieren.

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

Sie haben jedoch auch Recht mit Ihrem Rückrufkommentar. res.end();sollte sich innerhalb des Rückrufs befinden, direkt unter Ihren writeAnrufen.

loganfsmyth
quelle
Ja, das hat den Trick gemacht. Als Neuling wusste das nicht und vielen Dank.
Umutm
48

Ich erhalte diese Fehlermeldung und sie erwähnt options.body

Ich hatte das ursprünglich

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

Ich habe es so geändert:

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

und es scheint jetzt ohne die Fehlermeldung zu funktionieren ... scheint aber ein Fehler zu sein.

Ich denke, dies ist der offiziellere Weg, dies zu tun:

 request.post({
        url: apiServerBaseUrl + '/v1/verify',
        json: true,
        body: {
            email: req.user.email
        }
    });
Alexander Mills
quelle
4
Ihr Problem ist anders. Es wird standardmäßig erwartet, dass body eine Zeichenfolge oder ein Puffer ist. Sie können es auch ändern (um json serialisierbar zu sein), indem Sie json: true zu Optionen hinzufügen. Beispiel: request.post ({url: apiServerBaseUrl + '/ v1 / verify', body: {email: req.user.email}, json: true})
Nuno Tomas
2
Sie könnten dies verwenden, um stringify zu vermeidenjavascript request.post({ url: apiServerBaseUrl + '/v1/verify', json: { email: req.user.email } }
bsorrentino
13

Nun, offensichtlich versuchen Sie, etwas zu senden, das kein String oder Puffer ist. :) Es funktioniert mit der Konsole, weil die Konsole alles akzeptiert. Einfaches Beispiel:

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

Eine Möglichkeit, etwas in einen String umzuwandeln, besteht darin, Folgendes zu tun:

res.write( "" + obj );

wann immer Sie versuchen, etwas zu senden. Die andere Möglichkeit besteht darin, die .toString()Methode aufzurufen :

res.write( obj.toString( ) );

Beachten Sie, dass es möglicherweise immer noch nicht das ist, wonach Sie suchen. Sie sollten Strings / Puffer immer .writeohne solche Tricks übergeben.

Als Randnotiz: Ich gehe davon aus, dass dies requesteine asynchrone Operation ist. Wenn dies der Fall ist, res.end();wird vor jedem Schreiben aufgerufen, dh das Schreiben schlägt trotzdem fehl (da die Verbindung zu diesem Zeitpunkt geschlossen wird). Verschieben Sie diese Zeile in den Handler:

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( );
});
verrückt
quelle
Vielen Dank für die Antwort und die detaillierten Informationen. Und ja, ich habe den res.end in den Handler verschoben. Ich habe @loganfsmyth wie früher akzeptiert. Nochmals vielen Dank.
Umutm
1

Wenn Sie ein JSON-Objekt in die Antwort schreiben möchten, ändern Sie den Header-Inhaltstyp 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();
Mohsin Muzawar
quelle
1

Und es gibt eine andere Möglichkeit (in diesem Fall nicht), wenn Sie mit Ajax (XMLhttpRequest) arbeiten. Wenn Sie Informationen an das Client-Ende zurücksenden, sollten Sie res.send (Antworttext) anstelle von res.end (Antworttext) verwenden.

Prajith P.
quelle
1

Obwohl die Frage gelöst ist, Wissen zur Klärung der korrekten Bedeutung des Fehlers teilen.

Der Fehler besagt, dass der für die betreffende Unterbrechungsfunktion erforderliche Parameter nicht das erforderliche Format hat, dh Zeichenfolge oder Puffer

Die Lösung besteht darin, den Parameter in string zu ändern

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

oder Puffer

breakingFunction(BSON.serialize(offendingParameter), ... other params...);
Zameer
quelle
0

Das erste Argument muss vom Typ string oder Buffer sein. Empfangenes Typobjekt

 at write_

Ich habe den obigen Fehler erhalten, als ich Körperdaten an das Anforderungsmodul übergeben habe.

Ich habe einen anderen Parameter übergeben, der JSON ist: true und seine Funktionsweise.

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});})
A. PRABIN SARAB
quelle