nodejs-第一个参数必须是字符串或Buffer-与http.request一起使用response.write时


92

我只是试图创建一个输出给定URL的HTTP状态的节点服务器。

当我尝试使用res.write刷新响应时,出现错误:throw new TypeError('第一个参数必须是字符串或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);

我相信我应该在某个地方添加一个回调,但是很困惑,我们将提供任何帮助。

Answers:


31

请求采用回调方法,它是异步的!所以我假设,在执行回调时res.end()可能会调用它。尝试在回调中关闭请求。


1
做到了,还添加了.toString。非常感谢。
umutm

好像我忘了。刚刚做到了。谢谢。
umutm '16

1
@umutm还有更多精心编写和精心设计的答案,您可能应该接受其中一个。让任何人都可以看到这个问题。
Gaurav Agarwal

52

response.statusCode是一个数字,例如response.statusCode === 200,不是'200'。如错误消息所述,write期望a stringBufferobject,因此必须对其进行转换。

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

您对回调评论也很正确。res.end();应该在回调内部,就在您的write调用下方。


是的,这就是窍门。作为一个nodejs新手,不知道这一点,非常感谢。
umutm

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
您的问题有所不同,默认情况下,body应该是字符串或Buffer。您还可以更改它(使其可序列化为json),将json:true添加到选项中。例如: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 } }
bsorrentino

13

好吧,很明显,您正在尝试发送不是字符串或缓冲区的内容。:)它可以与控制台一起使用,因为控制台可以接受任何内容。简单的例子:

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

将任何内容转换为字符串的一种方法是:

res.write( "" + obj );

每当您尝试发送邮件时。另一种方法是调用.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

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.send(responsetext)而不是res.end(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});})
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.