在Flask(微网页框架)中,我们有一个视图:
@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']})
在模板中,我们有一个<a href="/download/adkdsk457jds/240p/mp4/">Download 240p Video</a>
链接,当点击它时,它应该开始下载该视频。
问题是:
在某些没有安装IDM等下载管理器的浏览器中,它运行良好。但IDM未能下载它。 IDM只挂在http://example.com/download/adkdsk457jds/240p/mp4/
Firefox自己的下载管理器就是这种情况。 Firefox只下载一个简单的.html页面,而不是实际的视频。
但是,如果没有安装IDM或其他下载管理器,视频会在Chrome中成功下载。
请帮助并告知为什么它不起作用。我需要在代码中更改某些内容吗?
答案 0 :(得分:1)
您尚未提供任何回复信息,包括内容类型;您需要复制有关原始响应的更多信息,以便传达您要返回的响应类型。否则使用默认值(由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应用的任何压缩。
某些下载管理员可能会尝试使用HTTP range request并行获取下载,即使服务器没有宣传它支持此类请求也是如此。您可能应该使用 406 Not Acceptable 响应(请求不支持的字节范围是Accept-*
违规)。您需要记录下载管理器发送的标头,以确保是否是这种情况。
答案 1 :(得分:0)
将'Content-Type': 'application/octet-stream'
添加到标题