你打电话后不会发送标题set_header()
; 它们不会被发送,直到您调用flush()
或finish()
(除其他外,如果在调用之前引发异常,则可以使用错误页面替换输出flush()
)
即使您打电话flush()
,整个服务器在通话期间也会被阻止urlopen()
.这是一个阻塞调用,必须用Tornado中的异步版本替换(有关详细信息,请参阅用户指南).Tornado提供了一个异步HTTP客户端,可用于代替urlopen()
:
@gen.coroutine def get(self): url = self.get_argument('url') filename = self.get_argument('filename') self.set_header('Content-Type', 'application/octet-stream') self.set_header('Content-Disposition', 'attachment; filename=%s' % filename) self.flush() response = yield AsyncHTTPClient().fetch(url) self.finish(response.body)
此过程一次将整个远程文件加载到内存中,并且在从远程服务器读取整个文件之前不会将任何文件发送到浏览器.如果文件很大,您可能希望以块的形式读取它并在读取它们时将它们发送回客户端:
# inside get() as above, after self.flush(): def streaming_callback(chunk): self.write(chunk) self.flush() yield AsyncHTTPClient().fetch(url, streaming_callback=streaming_callback) self.finish()