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


92

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

res.writeで応答をフラッシュしようとすると、次のエラーが表示されます。throw new TypeError( '最初の引数は文字列またはバッファである必要があります');

しかし、それらを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);

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

回答:


31

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


1
それを行い、.toStringも追加しました。どうもありがとう。
umutm 2013

忘れてしまったようです。やったところです。どうも。
umutm 16

1
@umutmより適切に記述された精巧な回答があります。おそらくそのうちの1つを受け入れる必要があります。この質問に来た人は誰でもそれを見ることができます。
Gaurav Agarwal

52

response.statusCodeは数値です。たとえばresponse.statusCode === 200、ではありません'200'。エラーメッセージにwrite示されているように、stringまたはBufferオブジェクトが必要なので、変換する必要があります。

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

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


はい、それでうまくいきました。nodejsの初心者として、それを知りませんでした。
umutm 2013

48

このエラーメッセージが表示され、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
        }
    });

4
あなたの問題は異なります、ボディはデフォルトで文字列またはバッファであると予想されます。オプションにjson:trueを追加して(jsonシリアライズ可能になるように)変更することもできます。例:request.post({url:apiServerBaseUrl + '/ v1 / verify'、body:{email:req.user.email}、json:true})
Nuno Tomas

2
これを使用して文字 javascript request.post({ url: apiServerBaseUrl + '/v1/verify', json: { email: req.user.email } }
列化

13

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

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

答えと詳細な情報を本当にありがとう。そして、はい、res.endをハンドラーに移動しました。以前と同じように、@ loganfsmythを受け入れました。もう一度。
umutm 2013

1

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

そして、ajax(XMLhttpRequest)を操作するときに別の可能性(この場合はありません)がありますが、クライアントエンドに情報を送り返すときは、res.end(responsetext)ではなくres.send(responsetext)を使用する必要があります。


1

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

エラーは、関係のある破壊関数に必要なパラメーターが、必要な形式(文字列またはバッファー)ではないことを示しています。

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

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

またはバッファ

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

0

最初の引数は、文字列型またはバッファ型のいずれかでなければなりません。受け取った型オブジェクト

 at write_

本文データをリクエストモジュールに渡すと、上記のエラーのようになりました。

JSONである別のパラメーターを渡しました。trueとその機能です。

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});})
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.