web-dev-qa-db-ja.com

nodejs-最初の引数は文字列またはバッファでなければなりません-response.writeをhttp.requestで使用する場合

特定のURLのHTTPステータスを出力するノードサーバーを作成しようとしています。

Res.writeで応答をフラッシュしようとすると、次のエラーが表示されます。throw new TypeError( 'first argument must be string or Buffer');

しかし、それらをconsole.logに置き換えると、すべて問題ありません(ただし、コンソールではなくブラウザに書き込む必要があります)。

コードは

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

どこかにコールバックを追加する必要があると思いますが、かなり混乱しており、どんな助けもありがたいです。

74
umutm

リクエストはコールバックメソッド、その非同期を取ります!したがって、コールバックが実行されるまでにres.end()が呼び出される可能性があります。コールバック内でリクエストを閉じてみてください!

24
Gaurav Agarwal

response.statusCodeは数値です(例: response.statusCode === 200ではなく、'200'。エラーメッセージに示されているように、writestringまたはBufferオブジェクトを想定しているため、変換する必要があります。

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

ただし、コールバックコメントについても正しいです。 res.end();は、コールバック内、write呼び出しのすぐ下にある必要があります。

50
loganfsmyth

私はこのエラーメッセージを受け取り、options.bodyに言及しています

元々これを持っていた

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

これに変更しました:

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

エラーメッセージなしで動作するようになりました...しかし、バグのようです。

これはもっと公式な方法だと思います:

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

さて、明らかに、文字列またはバッファではない何かを送信しようとしています。 :)コンソールは何でも受け入れるので、コンソールで動作します。簡単な例:

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

何かを文字列に変換する1つの方法は、それを行うことです。

res.write( "" + obj );

何かを送信しようとするたびに。もう1つの方法は、.toString()メソッドを呼び出すことです。

res.write( obj.toString( ) );

まだ探しているものではないかもしれないことに注意してください。このようなトリックなしで、常に文字列/バッファを.writeに渡す必要があります。

サイドノートとして:requestは非同期操作であると仮定します。その場合、書き込みの前にres.end();が呼び出されます。つまり、書き込みはとにかく失敗します(その時点で接続が閉じられるため)。その行をハンドラーに移動します。

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

また、ajax(XMLhttpRequest)を操作するときに別の可能性があります(この場合ではありません)。 res.send(responsetext) res.end(responsetext)の代わりに

1
Prajith P

問題は解決しましたが、エラーの正しい意味を明確にするための知識を共有しています。

エラーは、関連するブレーク関数に必要なパラメーターが必要な形式、つまり文字列またはバッファーにないことを示しています

解決策は、パラメータを文字列に変更することです

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

またはバッファ

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

応答にJSONオブジェクトを書き込みたい場合は、ヘッダーコンテンツタイプを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
Mohsin Muzawar