flask.Response 无法在 Web 浏览器中开始下载
Download doesn't start in web browser by flask.Response
在 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']})
在模板中,我们有一个 link 作为 <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 可以成功下载视频。
请帮助和建议为什么它不起作用。我需要更改代码吗?
将 'Content-Type': 'application/octet-stream'
添加到 headers
您没有包含任何响应信息,包括内容类型;您需要复制有关原始响应的更多信息,以传达您返回的响应类型。否则使用默认值(由 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
底层原始文件 object;这也应该有效,但还有一个额外的好处,即保留 YouTube 应用的任何压缩。
一些下载管理器可能会尝试使用 HTTP range request 来并行下载,即使服务器没有通告它支持此类请求。您可能应该使用 406 Not Acceptable 响应进行响应(在不支持的情况下请求字节范围是 Accept-*
违规行为)。您需要记录下载管理器发送的内容 headers 以确定是否属于这种情况。
在 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']})
在模板中,我们有一个 link 作为 <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 可以成功下载视频。
请帮助和建议为什么它不起作用。我需要更改代码吗?
将 'Content-Type': 'application/octet-stream'
添加到 headers
您没有包含任何响应信息,包括内容类型;您需要复制有关原始响应的更多信息,以传达您返回的响应类型。否则使用默认值(由 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
底层原始文件 object;这也应该有效,但还有一个额外的好处,即保留 YouTube 应用的任何压缩。
一些下载管理器可能会尝试使用 HTTP range request 来并行下载,即使服务器没有通告它支持此类请求。您可能应该使用 406 Not Acceptable 响应进行响应(在不支持的情况下请求字节范围是 Accept-*
违规行为)。您需要记录下载管理器发送的内容 headers 以确定是否属于这种情况。