You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
constKoa=require("koa");constapp=newKoa();constPORT=3000;app.use((ctx,_next)=>{constres=ctx.res;ctx.status=200;res.setHeader("Content-Type","text/html");res.write(`start<br>`);returnnewPromise(resolve=>{leti=0,total=5;while(i<=total){(function(i){setTimeout(()=>{if(i===total){resolve();res.end();}else{res.write(`${i}<br>`);}},i*1000);})(i);i++;}});});app.listen(PORT);console.info(`server started at http://localhost:${PORT}`);
Koa 中实现 chunked 数据传输
有关于
Transfer-Encoding:chunked
类型的响应,参见之前的文章HTTP 响应的分块传输。这里看 Koa 中如何实现。Koa 中请求返回的处理
虽然官方文档有描述说明不建议直接调用
response.write
:但要实现分片向客户端发送数据,必然还是得调用 Node.js Http 模块的 response.write(chunk[, encoding][, callback]) 方法,而这里的
response
就是ctx.res
或ctx.response
。所以为什么 Koa 要说不建议直接调用上述方法操作请求的返回呢,我们来看看 Koa 内部对 response 都会做些什么默认的处理。
application.js
在应用完各种中间件后(
fnMiddleware(ctx)
)通过handleResponse
对请求进行一些操作,最终是在respond
函数里。respond 方法
respond
方法里会根据外部是否有设置过ctx.body
,以及不同的 header 来设置ctx.body
,最终会调用response.end
来结束掉本次请求。注意到如果设置了
ctx.respond = false
,这个方法就直接return
了,这是一种跳过这里处理的方式。但其实如果我们在中间件中手动调用了ctx.res.end()
后,相当于已经提前结束掉请求了,同样也不会走 Koa 这里的处理。所以直接在中间件中调用
ctx.res.write()
及ctx.res.end()
就可以实现chunked
类型的响应,倒无须对 Koa 做额外设置。Koa 实现 chunked 数据传输
根据上面的分析,及之前一篇关于HTTP 响应的分块传输的文章,我们得出以下 Koa 中的实现逻辑:
运行效果:
Koa 中实现 chunked 响应的运行效果
如你所见,Koa 中的这个实现会在调用
ctx.res.end()
后将本来应该在页面内容中处于最顶部的内容,移动到最底部。不解。或者通过 curl 在命令行中查看效果:
命令行中接收 chunked 数据的效果
示例代码可在 wayou/koa-chunked-response 找到。
相关资源
The text was updated successfully, but these errors were encountered: