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 上传相同图片提示已存在

 

posted @ 2023-05-15 10:05  家乐福的搬砖日常  阅读(1417)  评论(0编辑  收藏  举报