flask(六)---flask上传文件
文件上传是很常见的功能,但这过程中却有很多技术环节需要学习
- 文件类型,大小限制
- 多文件上传
- 文件名称安全检查
1.文件大小限制
出于资源考虑,不能不对用户上传的文件大小进行限制,这个在flask中实现非常简单
from flask import Flask, Request app = Flask(__name__) app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024
超过16M大小的文件将无法上传
如果你使用nginx为你的flask服务做反向代理,那么nginx也需要进行配置,将nginx client_max_body_size 修改为合适的数值,该值默认是1M
2. 文件类型检查
如果你希望用户只上传jpg类型的图片,那么最简单的办法是对用户的文件名称后缀做检查
ALLOWED_EXTENSIONS = set(['jpg']) file = request.files['file'] def allowed_file(filename): return '.' in filename and \ filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS # 判断文件类型是否符合要求 file_ok = allowed_file(file.filename)
这种方法完全依赖用户上传的文件名称,但用户完全可以将其他类型的文件的名字修改成以jpg结尾,更准确稳妥的方法是通过检查文件内容来判断文件类型
python中有一个filetype库可以根据文件内容对文件类型进行判断,其原理是读取文件的前262字节的内容,而不同类型的文件拥有独特的文件头,关于文件头可以查阅这篇文章 https://blog.csdn.net/xiangshangbashaonian/article/details/80156865 ,filetype正是利用了不同文件头的内容不同进而判断一个文件的类型,下面是一段示例代码
import filetype kind = filetype.guess('1.jpeg') print('File extension: %s' % kind.extension) print('File MIME type: %s' % kind.mime)
3. 文件上传示例
3.1 代码结构图
3.2 相关代码
upload.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>上传文件</title> </head> <body> <form action="uploadfile" method=post enctype=multipart/form-data> <input type=file name=file id="file-input"> <button id="upload-btn" disabled>上传</button> </form> <script> const fileInput = document.getElementById('file-input'); const uploadBtn = document.getElementById('upload-btn'); fileInput.addEventListener('change', () => { if (fileInput.value) { uploadBtn.disabled = false; } else { uploadBtn.disabled = true; } }); </script> </body> </html>
文件上传.py
from flask import Flask, render_template, request, redirect, url_for import os app = Flask(__name__) # 设置上传文件的保存路径 app.config['UPLOAD_FOLDER'] = './upload' # 允许上传的文件类型 ALLOWED_EXTENSIONS = {'txt','pdf', 'png', 'jpg', 'jpeg', 'gif'} # 检查文件类型是否允许上传 def allowed_file(filename): return '.' in filename and \ filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS # 显示上传页面 @app.route('/') def index(): return render_template('upload.html') # 处理上传请求 @app.route('/uploadfile', methods=['POST']) def upload(): # 从请求中获取上传的文件 file = request.files['file'] # 如果文件已经存在,就提示该文件存在 if os.path.exists(os.path.join(app.config['UPLOAD_FOLDER'], file.filename)): #os.remove(os.path.join(app.config['UPLOAD_FOLDER'], file.filename))# 如果文件已经存在,就删除 return '文件已存在' # 检查文件类型是否允许上传 if file and allowed_file(file.filename): # 保存文件到指定路径 file.save(os.path.join(app.config['UPLOAD_FOLDER'], file.filename)) # 重定向到上传成功页面,并传递文件名参数 return redirect(url_for('success', filename=file.filename)) else: # 返回上传失败的提示信息 return '不支持上传格式,目前只支持txt,pdf, png, jpg, jpeg, gif' # 显示上传成功页面 @app.route('/success') def success(): # 获取上传成功页面的文件名参数 filename = request.args.get('filename') # 返回上传成功的提示信息 return f'{filename}上传成功' if __name__ == '__main__': app.run(debug=True)
4.运行效果:
4.1 上传图片测试
4.2 上传相同图片提示已存在