下载不会通过flask.Response在Web浏览器中启动

时间:2015-01-26 09:27:54

标签: python file stream flask python-requests

在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中成功下载。

请帮助并告知为什么它不起作用。我需要在代码中更改某些内容吗?

2 个答案:

答案 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'添加到标题