节点快速发送功能不适用于二进制数据

时间:2018-06-25 12:39:27

标签: node.js express

我在express中有一条GET路由,该路由应该返回存储在mongodb中的二进制png图像。但是,当我在chrome中输入网址进行测试时,下载了图片,但请求从未完成。在Chrome DevTools的“网络”标签中,请求只是停留在“待处理”状态。我似乎只是用二进制数据来解决这个问题。我还有很多其他的JSON GET请求,它们可以与send()一起正常工作。

我正在使用send()函数,如下所示:

exports.getProjectPng = (req, res) => {
  Project.findById(req.params.projectId).select('project.png')
    .then(project => {    
      res.send(project.png.buffer);
  });

如果我仅将send()替换为end(),则请求将按预期完成。另外,也许值得注意的是,png图像实际上是在浏览器中呈现的,而不是作为文件下载的。

那么end()为什么but send()不起作用?

2 个答案:

答案 0 :(得分:1)

如果您将curl指向快速服务器,然后查看两种方法的响应情况,那将非常有趣。主要区别是调用send时会填充Content-Type标头,这与Express文档一致:

当参数为Buffer对象时,除非事先定义,否则该方法会将Content-Type响应标头字段设置为“ application / octet-stream”

值得注意的是,res.send()实际上在调用结束时在内部调用了res.end(),因此除了res.end之外,其他行为很可能归结为res.send所做的事情。 >

可能值得在发送之前将示例中的Content-Type标头填充为“ image / png”。

例如

res.set('Content-Type', 'image/png');

对于.end():

* Connected to localhost (::1) port 8081 (#0)
> GET /downloadpng_end HTTP/1.1
> User-Agent: curl/7.30.0
> Host: localhost:8081
> Accept: */*
>
< HTTP/1.1 200 OK
< X-Powered-By: Express
< Date: Mon, 25 Jun 2018 13:14:58 GMT
< Connection: keep-alive
< Content-Length: 69040
<

对于send():

* Connected to localhost (::1) port 8081 (#0)
> GET /downloadpng_send HTTP/1.1
> User-Agent: curl/7.30.0
> Host: localhost:8081
> Accept: */*
>
< HTTP/1.1 200 OK
< X-Powered-By: Express
< Content-Type: application/octet-stream
< Content-Length: 69040
< ETag: W/"10db0-KwFSGG5Ib/DQNZChAbluTiKSP0o"
< Date: Mon, 25 Jun 2018 13:15:25 GMT
< Connection: keep-alive
<

答案 1 :(得分:0)

Nodejs不能很好地处理直接的二进制数据。因此,这就是用来处理二进制数据的缓冲区。

End() Method

end-没有更多数据可读取时,将触发此事件。而发送不能保证它是否完成。您可以在官方文档here

上了解有关缓冲区的更多信息