2013-02-12 56 views
44

我只是试图创建一个输出给定URL的HTTP状态的节点服务器。当我尝试使用res.write刷新响应时,出现以下错误:throw new TypeError('第一个参数必须是字符串或缓冲区');nodejs - 第一个参数必须是字符串或缓冲区 - 使用http.request时使用response.write

但是,如果我用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); 

我相信我应该的地方,但很困惑添加一个回调和任何帮助表示赞赏。

回答

8

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

+1

这是否也添加了.toString。非常感谢。 – umutm 2013-02-13 12:10:45

+0

@umutm为什么不是upvote? – 2016-12-20 09:52:58

+0

似乎我忘了。刚刚做到了。谢谢。 – umutm 2016-12-21 10:47:58

40

response.statusCode是一个数字,例如, response.statusCode === 200,而不是'200'。正如错误消息所述,write预计会出现stringBuffer对象,因此您必须对其进行转换。

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

你也对你的回调评论是正确的。 res.end();应位于回拨内,正好位于您的write通话的下方。

+0

是的,这确实起作用。作为一个nodejs新手,不知道这一点,并非常感谢。 – umutm 2013-02-13 12:08:10

12

好吧,显然你正在尝试发送一些不是字符串或缓冲区的东西。 :)它与控制台一起工作,因为控制台可以接受任何东西简单的例子:任何东西转换成字符串

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

非常感谢您的回答和详细信息。 而且,是的,我已将res.end移入处理程序。 我已经接受@loganfsmyth,因为它早些时候。 Thx再次。 – umutm 2013-02-13 12:10:12

11

我收到此错误消息,并提到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 
    }) 
} 

,似乎现在的工作不错误消息...似乎是错误虽然

+2

你的问题是不同的,身体默认预期是一个字符串或缓冲区。 你也可以改变它(要成为json序列化)添加json:true选项。 如: request.post({ 网址:apiServerBaseUrl + '/ V1 /验证', 正文:{电子邮件:req.user.email}, JSON:真 }) – 2017-04-05 10:45:51

+0

你可以利用这一点避免* * **字符串化 '''的JavaScript request.post({ 网址:apiServerBaseUrl + '/ V1 /验证', JSON:{ 电子邮件:req.user.email }} ''' – bsorrentino 2017-07-18 08:32:47

0

如果u想要一个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(); 
相关问题