Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 下载不';t在web浏览器中按flask启动。响应_Python_File_Stream_Flask_Python Requests - Fatal编程技术网

Python 下载不';t在web浏览器中按flask启动。响应

Python 下载不';t在web浏览器中按flask启动。响应,python,file,stream,flask,python-requests,Python,File,Stream,Flask,Python Requests,在Flask(micro web framework)中,我们的观点如下: @app.route('/download/<id>/<resolution>/<extension>/') def download_by_id(id, resolution=None, extension=None): stream = youtube.stream_url(id, resolution, extension) binary = requests.g

在Flask(micro web framework)中,我们的观点如下:

@app.route('/download/<id>/<resolution>/<extension>/')
def download_by_id(id, resolution=None, extension=None):
    stream = youtube.stream_url(id, resolution, extension)
    binary = requests.get(stream['url'], stream=True)
    return flask.Response(
        binary,
        headers={'Content-Disposition': 'attachment; '
                                        'filename=' + stream['filename']})
@app.route('/download//'))
def下载者id(id,分辨率=无,扩展名=无):
stream=youtube.stream\uURL(id、分辨率、扩展名)
binary=requests.get(stream['url'],stream=True)
返回烧瓶。响应(
二元的,
headers={'Content-Disposition':'attachment;'
'filename='+流['filename']})
在模板中,我们有一个链接,名为
,单击它时,它应该开始下载该视频

问题是:

它在一些没有安装IDM等下载管理器的浏览器中运行良好。但IDM无法下载它。IDM只是挂起在
http://example.com/download/adkdsk457jds/240p/mp4/

Firefox自己的下载管理器也是如此。Firefox只下载一个普通的.html页面,而不是实际的视频

但是,如果没有安装IDM或其他下载管理器,则可以在Chrome中成功下载视频


请帮助和建议它为什么不起作用。是否需要更改代码中的某些内容?

'Content-Type':'application/octet-stream'
添加到标题中

您没有包含任何响应信息,包括内容类型;您需要复制更多关于原始响应的信息,以传达返回的响应类型。否则将使用默认值(由HTTP标准或Flask指定)

具体来说,至少您希望跨内容类型、长度和传输编码进行复制:

headers={
    'Content-Disposition': 'attachment; filename=' + stream['filename']
}
for header in ('content-type', 'content-length', 'transfer-encoding'):
    if header in binary.headers:
        headers[header] = binary.headers[header]
return flask.Response(binary.raw, headers=headers)
我使用的是
response.raw
底层原始文件对象;这应该也能起作用,但还有一个额外的优势,那就是YouTube应用的任何压缩都会被保留


一些下载管理器可能会尝试使用一个来并行获取下载,即使服务器没有公布它支持这样的请求。您可能应该使用406不可接受的响应进行响应(不受支持时请求字节范围是一种
Accept-*
冲突)。您需要记录下载管理器发送的标题,以确定是否存在这种情况。

您是否尝试更改url,使其以
.mp4
结尾?按url,您的意思是将文件名更改为video1.mp4还是什么?您的
路由
参数和
href
包含什么内容。@BartoszMarcinkowski,我不确定你所说的href是什么意思,但这里的
href
指的是我上面展示的烧瓶视图。所以不确定添加扩展会有什么帮助?下载管理器希望能够使用HTTP范围请求;烧瓶未设置为进行范围设置。我怀疑这就是问题的原因。我只是给了你一个提示,因为你提到“Firefox只下载一个普通的.html页面”。我认为http范围应该始终与内容类型相结合。嗯,对我来说,它工作起来很有魅力。:-)只需将其添加到标题中,下载管理器就可以正确捕获文件。但是仍然缺少下载管理器的
剩余时间
文件大小
,需要做什么?不,HTTP范围适用于任何mimetype。例如,AcrobatReader广泛使用它来提前加载特定页面。视频播放器在您跳过已缓冲的视频部分时使用它。下载经理使用它来并行下载视频中的不同部分。但是,如果YouTube的回复中有正确的内容类型,那么盲目地将内容类型设置为
application/octet stream
是错误的做法。通常,使其可下载是正确的做法。这是什么
response
您指的是?@cracock:抱歉,您在代码中将其命名为
binary
。使用此
binary
,是否有任何方法可以确定
文件大小和
运行时间
?这样它就可以被发送到
头文件中
供下载管理员捕获。@cracock:
内容长度
是文件大小;不知道你在这里所说的时间是什么意思;还有一个
日期
标题,你也可以复制。它不适用于流的
内容类型
,假设
视频/3gpp
(它只是挂起,从不在下载管理器中启动下载),但如果我专门将其设置为
应用程序/octet流
,一切正常。有办法解决吗?与烧瓶有关。响应