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 建立一个 ...
随机推荐
- find与tar的结合使用
新建一个文件,自定义时间点[root@nhserver2 ~]# touch -t 1403010000.00 file1.txt 新建一个文件,自定义时间点[root@nhserver2 ~]# ...
- pat 1022 digital library
#include <iostream> #include <sstream> #include <string> #include <vector> # ...
- 跳转语句Break、continue
跳转语句Break.continue 1.break -跳出 作用范围:switch或循环语句; -当break语句单独存在时,下面不需要定义其他语句,因为直接被跳出,不执行下面的语句. -break ...
- 集中式(SVN)和分布式(Git)版本控制系统的简单比较
集中式(SVN) 分布式(Git) 是否有中央服务器 有.开发人员需要从中央服务器获得最新版本的项目然后在本地开发,开发完推送给中央服务器.因此脱离服务器开发者是几乎无法工作的 没有中央 ...
- 日常API之图灵聊天机器人
机器人是什么?可以吃吗? 嗯,他可以和你聊天,不能吃哦. 首先需要到www.tuling123.com注册一只KEY,你才能调用机器人API哦 一.布局 (控制台程序可以跳过这一步)本文以WPF为示例 ...
- flask----flask-session
一.flask-session flask-session是flask框架的session组件,由于原来flask内置session使用签名cookie保存,该组件则将支持session保存到多个地方 ...
- Animations and transitions
在交互式可视化中,有一个词叫reactive,指的是以可视化的方式来响应用户的行为,帮助用户进行可视化并理解其结果.这个很有用.那如何来实现这种交互呢?通过动画. 如果处理得当,动画可以展现出不错的可 ...
- c# 实现mysql事务
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- 安装phpredis-master步骤备忘
下载软件包下载地址: http://pan.baidu.com/s/1i37R8TB 解包 tar -zxvf phpredis-master.tar.gz cd phpredis-master /o ...
- 完全总结bash中的条件判断test [ [[ 使用
在bash脚本编程中,我们经常做一些条件判断, 我们主要用到了三种,test,单中括号,双中括号 经常有看到不同的写法,如: [ $? –eq ] [[ $myvar == “mysql” ]] te ...