Flask上传文件

文件上传的基本原理实际上很简单,基 本上是:

  1. 一个带有 enctype=multipart/form-data<form> 标记,标记中含有 一个 <input type=file>
  2. 应用通过请求对象的 files 字典来访问文件。
  3. 使用文件的 save() 方法把文件 永久地保存在文件系统中。

例,上传文件html页:

<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="img">
<input type="submit" value="上传">
</form>

让我们从一个基本的应用开始,这个应用上传文件到一个指定目录,并把文件显示给 用户。

以下是应用的前导代码:

import os,sys
from flask import Flask, flash, request, redirect, url_for
from werkzeug.utils import secure_filename # 为了便于迁移,上传文件的路径使用了os模块来寻找当前文件夹拼接windows文件分隔符再拼接真正的目录名,
# 例如我的就是uploads,最后再加上一个文件分隔符即可。
UPLOAD_FOLDER =os.path.curdir+os.path.sep+'uploads'+os.path.sep
ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif']) app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

首先我们导入了一堆东西,大多数是浅显易懂的。 werkzeug.secure_filename() 会在稍后解释。 UPLOAD_FOLDER 是上传文 件要储存的目录, ALLOWED_EXTENSIONS 是允许上传的文件扩展名的集合。

注:为了便于迁移,上传文件的路径我使用了os模块来寻找当前文件夹拼接windows文件分隔符再拼接真正的目录名。例如我的就是uploads,最后再加上一个文件分隔符即可。

python中os.path常用模块:

os.path.sep -->windows路径分隔符
os.path.altsep -->linux下就用:'/' 根目录:os.path.curdir
当前目录:os.path.pardir
父目录:os.path.abspath(path)
绝对路径:os.path.join() 常用来链接路径:os.path.split(path),把path分为目录和文件两个部分,以列表返回。
  • 为什么要限制文件的扩展名呢?

如果直接向客户端发送数据,那么你可能不会想让用户上传任意文件。否则,你必须确保用户不能上传 HTML 文件,因为 HTML 可能引 起 XSS 问题(参见 跨站脚本攻击(XSS) )。如果服务器可以执行 PHP 文件,那么还必须确保不允许上传 .php 文件。

下一个函数检查扩展名是否合法,上传文件,把用户重定向到已上传文件的 URL:

def allowed_file(filename):
# 获取文件扩展名,以'.'为右分割然后取第二个值
return '.' in filename and \
filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS @app.route('/', methods=['GET','POST'])
def upload_file():
if request.method == 'POST':
# check if the post request has the file part
if 'file' not in request.files:
flash('No file part')
return redirect(request.url)
file = request.files['file']
# 如果没有选择文件,浏览器也可以提交一个没有文件名的空部分
if file.filename == '':
flash('No selected file')
return redirect(request.url)
# 如果有文件且文件扩展名允许
if file and allowed_file(file.filename):
filename = secure_filename(file.filename)
# 拼接保存文件路径
file.save(os.path.join(app.config['UPLOAD_FOLDER'],filename))
# 返回反向解析得到的URL
return redirect(url_for('uploaded_file', filename=filename))
return '''
<!doctype html>
<title>Upload new File</title>
<h1>Upload new File</h1>
<form method=post enctype=multipart/form-data>
<input type=file name=file>
<input type=submit value=Upload>
</form>
'''

那么 secure_filename() 函数到底是有什么用?

有一条原则是“永远不要信任用户输入”

这条原则同样适用于已上传文件的文件名。所有提交的表单数据可能是伪造的,文件名也可以是危险的。此时要谨记:在把文件保存到文件系统之前总是要使用secure_filename这个函数对文件名进行安检。

进一步说明

你可以会好奇 secure_filename() 做了哪些工作,如果 不使用它会有什么后果。假设有人把下面的信息作为 filename 传递给你的应 用:

filename = "../../../../home/username/.bashrc"

假设 ../ 的个数是正确的,你会把它和 UPLOAD_FOLDER 结合在一起,那 么用户就可能有能力修改一个服务器上的文件,这个文件本来是用户无权修改的。 这需要了解应用是如何运行的,但是请相信我,黑客都是很变态的

FLask上传文件的更多相关文章

  1. flask上传文件到指定路径

    flask上传文件到指定路径 项目结构如下: 首先是:视图函数uload_file.py,代码如下: #!/usr/bin/env python # -*- coding: utf-8 -*- fro ...

  2. flask 上传文件

    flask upload 近日在学习python,接触到了flask框架,刚好客户有个需求,需要在网页上传一个python 代码的zip包,然后使用docker 容器运行这个zip里面的程序,输出结果 ...

  3. 记一次flask上传文件返回200前端却504的问题

    前言 好久没写了, 主要是太忙了, 本篇记一下今天解决的一个问题吧, 耗了我大半天的时间才解决 问题 今天在调试代码时, 发现了一个诡异的问题, 我之前写了一个接口, 作用是接收上传的文件, 因为这个 ...

  4. flask上传文件时request.files为空的解决办法

    在做上传文件的时候遇到request.files是空 原因在于html中的表单form没有指明 enctype="multipart/form-data" <form met ...

  5. windows python flask上传文件出现IOError: [Errno 13] Permission denied: 'E:\\git\\test\\static\\uploads'的解决方法

    在浏览器中输入时,出现IOError: [Errno 13] Permission denied: 'E:\\git\\test\\static\\uploads' http://127.0.0.1: ...

  6. Flask -- 请求、上传文件、Cookies

    请求对象 from flask import request request.method #值为form表单提交的method 'POST'. 'GET'等 #如果值为'POST'或'PUT',则可 ...

  7. flask jQuery ajax 上传文件

    1.html 代码 <div> <form id="uploadForm" enctype="multipart/form-data" > ...

  8. Ajax+Python flask实现上传文件功能

    HTML: <div > <input type="file" name="FileUpload" id="FileUpload&q ...

  9. flask插件系列之flask_uploads上传文件

    前言 flask可以实现上传文件和下载文件的基本功能,但如果想要健壮的功能,使用flask_uploads插件是十分方便的. 安装 pip install flask_uploads 基本使用 # e ...

随机推荐

  1. 关于爬虫中常见的两个网页解析工具的分析 —— lxml / xpath 与 bs4 / BeautifulSoup

    http://www.cnblogs.com/binye-typing/p/6656595.html 读者可能会奇怪我标题怎么理成这个鬼样子,主要是单单写 lxml 与 bs4 这两个 py 模块名可 ...

  2. 这是一位拿到BAT大厂offer应届生的年终总结,那么你的呢?

    壹 关于求职 2018年初,我还在北京后厂村的马路上被风吹得瑟瑟发抖. 那时我刚刚结束了半年的实习时光,开始考虑年后是否要继续实习.一开始我也在纠结实习转正和秋招之间如何权衡,但是在经历了春招以后,我 ...

  3. 从零开始学 Web 之 jQuery(四)元素的创建添加与删除,自定义属性

    大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...

  4. Kafka实战-Storm Cluster

    1.概述 在<Kafka实战-实时日志统计流程>一文中,谈到了Storm的相关问题,在完成实时日志统计时,我们需要用到Storm去消费Kafka Cluster中的数据,所以,这里我单独给 ...

  5. Unity3D鼠标坐标转世界坐标和局部坐标

    鼠标坐标转世界坐标和局部坐标: Vector3 MousePosition2Local () { mousePosition = Input.mousePosition; //获取屏幕坐标 mouse ...

  6. Apollo 2 如何支持 @Value 注解自动更新

    前言 Apollo 在 v0.10.0 版本后,支持自动更新.v0.10.0之前的版本在配置变化后不会重新注入,需要重启才会更新. 也就是说,如果一个属性加入了 @Value 注解,并且这个配置在配置 ...

  7. Spring Boot 初始化运行特定方法

    Spring Boot提供了两种 “开机自启动” 的方式,ApplicationRunner和CommandLineRunner 这两种方式的目的是为了满足,在容器启动时like执行某些方法.我们可以 ...

  8. 菜鸟入门【ASP.NET Core】11:应用Jwtbearer Authentication、生成jwt token

    准备工作 用VSCode新建webapi项目JwtAuthSample,并打开所在文件夹项目 dotnet new webapi --name JwtAuthSample 编辑JwtAuthSampl ...

  9. Java学习笔记之——变量与数据类型、运算符

    一.变量 1.变量:变化的值 变量在代码运行期间,开辟了一块空间 .这块空间是有地址的,给这块取了个名字, 这个名字就叫做变量名,这块空间放的东西叫做变量值 2.变量的初始化: (1)先声明再赋值: ...

  10. idea 中使用 jetty 插件

    参考博客:http://blog.csdn.net/xiejx618/article/details/49936541