我正在构建一个flask函数,该函数将文件发送给用户进行下载,并在文件发送后迅速将其删除。我设法用发电机做到了。但是,在测试中,发送给用户的文件与原始文件(.res)的格式完全不同(download.htm)。如何指定要保留在.res
中的文件类型?
这就是我所拥有的:
@app.route('/download')
def download_file():
file_pathres = dirname(realpath(__file__)) + '/' + pathres
file_pathtxt = dirname(realpath(__file__)) + '/' + pathtxt
print('download file path: ' + file_pathres)
#file_path = derive_filepath_from_filename(filename)
file_handle = open(file_pathres, 'r')
# This *replaces* the `remove_file` + @after_this_request code above
def stream_and_remove_file():
yield from file_handle
file_handle.close()
os.remove(file_pathres)
os.remove(file_pathtxt)
return current_app.response_class(
stream_and_remove_file(),
headers={'Content-Disposition': 'attachment'}
)
我应该在标题或return语句中进行哪些更改,以确保发送的格式与最初打开和删除的文件的格式相同?
答案 0 :(得分:0)
默认情况下,实际文件名永远不会发送到客户端。 filename是来自操作系统的标识符,而不是文件本身的某些属性。就像指针的名称一样,它指向内存或驱动器上存储该文件内容的位置。通过网络发送文件时,仅发送其内容,原始数据以及一些信息标头。如果需要,您可以在此处指定一个指令,供客户端在其文件系统上设置文件名(如下所述)。
如果没有其他指定,浏览器将仅使用请求的端点(/download
)和来自{{3}的media-type
(或MIME-Type
)参数之类的标头信息}响应的标题以提供适当的文件名。在Flask中,默认Response
类将每个响应的MIME-Type
设置为text/html
,如果没有另外指定(Content-Type
)。
因此,在您的情况下,浏览器将端点/download
作为文件名,并根据MIME-Type
选择扩展名,即text/html
=> donwload.html
您可以继承Response
类并自定义默认行为,这会影响您的所有响应,也可以设置应在浏览器中“另存为”中显示的文件名(以及扩展名)。对话框,每个响应的source标头中的filename
参数:
return app.response_class(
stream_and_remove_file(),
headers={'Content-Disposition': "attachment; filename=testfile.res"}
)
attachment
属性仅告诉浏览器将响应内容下载为文件,而不尝试呈现它们。
答案 1 :(得分:0)
找到了解决方法:
r = current_app.response_class(stream_and_remove_file(), mimetype='text')
r.headers.set('Content-Disposition', 'attachment', filename="filename.res")
return r
设置标题时,请在filename参数中指定文件类型,强制发送文件为该格式。