Flask下载文件
前言
由于最近在做文件管理模块的功能,所以难免会遇到文件上传下载这块的功能。不过文件上传那块是调用的OSS api,所以接触的不多。
文件的下载:
1. 接口返回真实的文件
这种情况比较简单, flask里带有此类api, 可以用send_from_directory和send_file.
核心代码如下:
from flask import send_file, send_from_directory
import os
@app.route("/download/<filename>", methods=['GET'])
def download_file(filename):
# 需要知道2个参数, 第1个参数是本地目录的path, 第2个参数是文件名(带扩展名)
directory = os.getcwd() # 假设在当前目录
return send_from_directory(directory, filename, as_attachment=True)
后边那个as_attachment参数需要赋值为True,不过此种办法有个问题,就是当filename里边出现中文的时候,会报如下错误:
解决办法:
使用flask自带的make_response
代码修改如下
from flask import send_file, send_from_directory
import os
from flask import make_response
@app.route("/download/<filename>", methods=['GET'])
def download_file(filename):
# 需要知道2个参数, 第1个参数是本地目录的path, 第2个参数是文件名(带扩展名)
directory = os.getcwd() # 假设在当前目录
response = make_response(send_from_directory(directory, filename, as_attachment=True))
response.headers["Content-Disposition"] = "attachment; filename={}".format(file_name.encode().decode('latin-1'))
return response
使用make_response函数建立一个response对象,然后将filename编码转为latin-1,可以看到server.py里边会严格按照latin-1编码来解析filename,所以我这里的做法是先将utf8编码的中文文件名默认转为latin-1编码。
2. 接口返回文件数据流
这种情况比较适合我现在的需求,因为我这边是用requests库,先请求一个oss链接,获取到文件的数据,然后我发现目前flask没有这样的api实现,这里还是使用make_response方法实现。
代码如下:
import mimetypes
@app.route('/fileManager/download/<projId>/<id>/<filename>', methods=['GET'])
def download_file(projId, id, filename):
try:
url = "your url"
r = requests.get(url, timeout=500)
if r.status_code != 200:
raise Exception("Cannot connect with oss server or file is not existed")
response = make_response(r.content)
mime_type = mimetypes.guess_type(filename)[0]
response.headers['Content-Type'] = mime_type
response.headers['Content-Disposition'] = 'attachment; filename={}'.format(filename.encode().decode('latin-1'))
return response
except Exception as err:
print('download_file error: {}'.format(str(err)))
logging.exception(err)
return Utils.beop_response_error(msg='Download oss files failed!')
解释一下:
make_response很强大,下载一个文件,需要在response的headers里边添加一些信息,比如文件的类型,文件的名字,是否以附件形式添加,这3个是比较关键的信息。
mime_type是文件的类型,我观察send_file的源代码发现里边用到了mimetypes.guess_type()这个方法,也就是猜测文件的类型,然后这里我就直接搬过来用了哈哈,r.content其实就是文件的数据流,之前我是通过
with open(filename, 'wb') as file:
file.write(r.content)
这样实现下载文件到本地的,所以其实r.content是一个文件数据流,也不清楚我的名词用的是否恰当哈哈。
之所以不用第一种方式,是因为我本地生成文件了之后,需要删除他,但是删除的时候总是会提示该文件已经被另一个程序使用,所以猜测是send_file这个api还在使用该文件,为了达到更好的效果,找到了第二种解决办法。
其实还有一种解决办法:
3. 发送静态文件
其实原来和第一种差不多,调用的api不一样,api是
from flask import app
import os
@app.route("/download/<filepath>", methods=['GET'])
def download_file(filepath):
# 此处的filepath是文件的路径,但是文件必须存储在static文件夹下, 比如images\test.jpg
return app.send_static_file(filepath)
Flask下载文件的更多相关文章
- flask下载文件中文IE,Edge,Safari文件名乱码
flask(0.11.2)+python3.6 兼容各个主流浏览器,已经过各种测试(chrome,firefox,safari,IE,Edge) quote是将文件名urlencode化,然后以适应E ...
- flask下载文件---文件流
html: <a name="downloadbtn" class="btn btn-success pull-right" href="/do ...
- flask 下载本地文件
下载本地文件就是找到文件路径 调用flask自带的send_file(路径)下载, 并返回 flask: # 下载文件 from flask import send_file@task_mgm.ro ...
- flask下载zip文件报错TypeError
报错内容:TypeError: make_conditional() got an unexpected keyword argument 'accept_ranges' 报错行自己代码如下: dir ...
- flask上传下载文件(一)下载
简介: 作为一个可以和用户交互的web应用,必然要有数据导出功能,导出到excel是比较常用的方式. flask有一个扩展叫flask-excel,可能不适合中国人用,因为没有看到修改列名的功能.也许 ...
- Flask 静态文件缓存问题
大家好,今天才发现很多学习Flask的小伙伴都有这么一个问题,清理缓存好麻烦啊,今天就教大家怎么解决. 大家在使用Flask静态文件的时候,每次更新,发现CSS或是Js或者其他的文件不会更新. 这是因 ...
- FastApi下载文件
FastApi下载文件 记得之前我们讲过生成excel文件的事情,那么如何把服务器生成的excel文件正确发送给用户呢? 今天我们就来说说在FastApi中如何正确让用户下载到想要的文件. 基本流程 ...
- Java下载文件(流的形式)
@RequestMapping("download") @ResponseBody public void download(HttpServletResponse respons ...
- 使用批处理文件在FTP服务器 上传下载文件
1.从ftp服务器根目录文件夹下的文件到指定的文件夹下 格式:ftp -s:[配置文件] [ftp地址] 如:ftp -s:c:\vc\ftpconfig.txt 192.168.1.1 建立一个 ...
随机推荐
- linkin大话数据结构--泛型
泛型(Generic) 什么是泛型? java5开始出现的一种对Java语言类型的一种拓展,以支持创建可以按类型进行参数化的类.可以把类型参数看作是使用参数类型时指定的类型占位符,就好比方法的形式参数 ...
- Eclipse设置代码自动提示
Eclipse只需几步简单的设置就可以像idea那样代码自动提示了,喜欢的小伙伴可以赶紧动手设置,提升效率. 第一步:打开Eclipse --> Window --> Preference ...
- PHP7.1 报错 Warning Illegal string offset
报错如下: Warning: Illegal string offset '阿根廷' in F:\wnmp\www\test.php on line 24 Warning: Illegal strin ...
- ------- 软件调试——挫败 QQ.exe 的内核模式保护机制 -------
------------------------------------------------------------------------ QQ 是一款热门的即时通信(IM)类工具,在安装时刻会 ...
- CentOS(Linux)下安装dmidecode包
安装代码: yum install dmidecode 安装完成后,查看总体信息: dmidecode 查看服务器类型,测试环境为DELL R610: dmidecode -s system-prod ...
- Java中常见的排序方法
本博主要介绍Java中几种常见的排序算法: /* 排序方法的演示1)插入排序(直接插入排序.希尔排序)2)交换排序(冒泡排序.快速排序)3)选择排序(直接选择排序.堆排序)4)归并排序5)分配排序(基 ...
- JQuery Ajax 设置请求头信息application/json
今天有个api后台接application/json格式的 在Jquery里$.ajax默认是contentType: application/x-www-form-urlencoded; chars ...
- JDBC访问及操作SQLite数据库
SQLite 是一个开源的嵌入式关系数据库,其特点是高度便携.使用方便.结构紧凑.高效.可靠. 与其他数据库管理系统不同,SQLite 的安装和运行非常简单,在大多数情况下,只要确保SQLite的二进 ...
- BZOJ 1801: [Ahoi2009]chess 中国象棋 [DP 组合计数]
http://www.lydsy.com/JudgeOnline/problem.php?id=1801 在N行M列的棋盘上,放若干个炮可以是0个,使得没有任何一个炮可以攻击另一个炮. 请问有多少种放 ...
- u-boot核心初始化
异常向量表:异常:因为内部或者外部的一些事件,导致处理器停下正在处理的工作,转而去处理这些发生的事件.ARM Architecture Reference Manual p54页.7种异常的类型:Re ...