H5W3
当前位置:H5W3 > 其他技术问题 > 正文

python 有没有办法实现类似反向代理(服务器边下载资源边向用户提供下载)的功能?

服务器一边获取外部网络资源,一边向客户输出,不必等服务器获取完全部。可以实现吗?
现在的方案是 httplib 获取资源然后 tornado 输出,,但是用户等待时间太长了。

回答:

我理解你的问题是不希望在服务器上从远程下载文件完毕,再传给用户,而是希望从远程下载一点就传给用户一点,直到完成是吧?

建议你用requests库,将stream设置为True

rf = requests.get(url, stream=True)
for chunk in rf.iter_content(chunk_size=1024*10): 
    if not chunk: break
    response.write(chunk)

因为不知道你的web服务器是什么,上面代码就表达这么个意思,希望能有用。

回答题主,在你评论的评论里,我不知道怎么贴代码。。汗。。。我就写在这里吧。

看到你的代码,确定你用的是tornado,那可以知道代码问题在于你仅仅将获取文件那里开启了流模式,但是你的tornado返回客户端数据没有开启流模式,将你的代码简单改一下(因为你那个下载文件的url我这里不知道为什么不能访问,我这里是从百度下载jdk),换句话说,要用流的方式读取,也要用流的方式发送:

#!/usr/bin/env python
# -*- coding:utf-8 -*-
import requests
import tornado.ioloop
import tornado.web
from tornado import gen

class MainHandler(tornado.web.RequestHandler):
    @gen.coroutine  #流方式注解
    def get(self):
        rf = requests.get('http://dlsw.baidu.com/sw-search-sp/soft/10/25851/jdk-8u40-macosx-x64.1427945120.dmg', stream=True)
        for chunk in rf.iter_content(chunk_size=1024*10):
            if not chunk: break
            self.write(chunk)
            self.flush()  #写一点就发送一点


application = tornado.web.Application([
    (r"/", MainHandler),
])

if __name__ == "__main__":
    application.listen(8080)
    tornado.ioloop.IOLoop.instance().start()

你再试试,我用命令:wget http://127.0.0.1/:8080 -O jdk.dmg命令,立刻可以看到有下载进度,如果将1024*10改成1024*10*10,估计你会看到下载进度是1M,1M的增加的。

图片描述

希望对你有用,谢谢

本文地址:H5W3 » python 有没有办法实现类似反向代理(服务器边下载资源边向用户提供下载)的功能?

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址