Flask-实现下载功能
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(excel_path, filename.encode('utf-8').decode('utf-8'), as_attachment=True))
response.headers["Content-Disposition"] = "attachment; filename={}".format(filename.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. 发送静态文件
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-实现下载功能的更多相关文章
- 06_Linux基础-NGINX和浏览器、网页的关系-云服务器ssh登陆-安装NGINX-上传网页-压缩命令-xz-gzip-bzip2-zip-tar-配置NGINX服务器支持下载功能-备份脚本
06_Linux基础-NGINX和浏览器.网页的关系-云服务器ssh登陆-安装NGINX-上传网页-压缩命令-xz-gzip-bzip2-zip-tar-配置NGINX服务器支持下载功能-备份脚本 一 ...
- iNeedle日志下载功能问题
问题: iNeedle系统本身包含日志下载功能,主要是将web服务器中的用户访问日志按照一定条件进行筛选并下载,提供管理者分析.但是这次的测试中发现iNeedle日志下载一直会卡住,web界面显示正在 ...
- Safari 下用 "location.href = filePath" 实现下载功能的诡异 bug
Safari 下的一些诡异 bug 我们已经领教一二,比如前文中说的 无痕浏览模式下使用 localStorage 的 API 就会报错.今天我们要讲的是利用 location.href = file ...
- location.href 实现点击下载功能
如果页面上要实现一个点击下载的功能,传统做法是使用一个 a 标签,然后将该标签的 href 属性地址指向下载文件在服务端的地址(相对地址或者绝对地址),比如这样: 能这样实现是因为,在浏览器地址栏输入 ...
- php实现文件上传下载功能小结
文件的上传与下载是项目中必不可少的模块,也是php最基础的模块之一,大多数php框架中都封装了关于上传和下载的功能,不过对于原生的上传下载还是需要了解一下的.基本思路是通过form表单post方式实现 ...
- JavaWeb学习记录(一)——response响应头之缓存设置与下载功能的实现
一.HTTP中常用响应头 Location: http://www.it315.org/index.jsp Server:apache tomcat Content-Encoding: gzip Co ...
- JavaWeb实现文件上传下载功能实例解析
转:http://www.cnblogs.com/xdp-gacl/p/4200090.html JavaWeb实现文件上传下载功能实例解析 在Web应用系统开发中,文件上传和下载功能是非常常用的功能 ...
- 【转】Android 服务器之SFTP服务器上传下载功能
原文网址:http://blog.csdn.net/tanghua0809/article/details/47056327 本文主要是讲解Android服务器之SFTP服务器的上传下载功能,也是对之 ...
- wuzhicms字段的添加以及实现下载功能
1.字段的添加 发布内容--> 栏目管理--> 字段管理-->添加字段 下面根据需求进行相应的设置. 然后提交即可. 2.下载功能的实现 实例说明: 会员中心相关页面下载功能的实现 ...
- windows下实现uboot的tftp下载功能
一.原理分析 带有uboot的开发板实际上充当的就是tftp客户端,而PC机扮演的角色就是tftp服务器端,而tftp下载功能实际上就是文件传输.tftp服务器可以建立在虚拟机linux下,也可以建立 ...
随机推荐
- 「MoreThanJava」Java发展史及起航新世界
「MoreThanJava」 宣扬的是 「学习,不止 CODE」,本系列 Java 基础教程是自己在结合各方面的知识之后,对 Java 基础的一个总回顾,旨在 「帮助新朋友快速高质量的学习」. 当然 ...
- Java 设置Excel单元格格式—基于Spire.Cloud.SDK for Java
本文介绍使用Spire.Cloud.SDK for Java来设置Excel单元格格式,包括字体.字号.单元格背景.字体下滑线.字体加粗.字体倾斜.字体颜色.单元格对齐方式.单元格边框等 一.下载SD ...
- react中使用decorator 封装context
2020-03-27 react中使用decorator 封装context 在传统的react context中,子组件使用context十分繁琐,如果需要使用context的子组件多的话 每个组件 ...
- TCP 三次握手的意义
概述 在网络的传输层协议中, 存在着两大悍将: TCP 和 UDP . 从前, 我傻傻的以为自己对他们虽谈不上精通, 但还是知道的, 但是, 我错了, 我被自己问住了, 我傻了. 啥也不是. UDP ...
- 04 . Docker安全与Docker底层实现
Docker安全 Docker安全性时,主要考虑三个方面 # 1. 由内核的名字空间和控制组机制提供的容器内在安全 # 2. Docker程序(特别是服务端)本身的抗攻击性 # 3. 内核安全性的加强 ...
- flink实时数仓从入门到实战
第一章.flink实时数仓入门 一.依赖 <!--Licensed to the Apache Software Foundation (ASF) under oneor more contri ...
- tkinter操作练习一
# -*- utf-8 -*- #@Time :2019/8/2723:17 #@Author :无邪 #@File :t_ui.py #@Software:PyCharm import tkinte ...
- 循序渐进VUE+Element 前端应用开发(12)--- 整合ABP框架的前端登录处理
VUE+Element 前端是一个纯粹的前端处理,前面介绍了很多都是Vue+Element开发的基础,从本章随笔开始,就需要进入深水区了,需要结合ABP框架使用(如果不知道,请自行补习一下我的随笔:A ...
- 阿里云Ubuntu配置mysql+navicat连接
一>mysql安装配置(工具:Xshell6) 1.安装mysql apt-get install mysql-server mysql-client 2.查看安装:查看版本 sudo ...
- opencv C++极坐标变换
#include<opencv2/core/core.hpp> #include<opencv2/highgui/highgui.hpp> #include<opencv ...