flask处理文件上传

在这里插入图片描述

flask处理文件上传

在Flask框架中,你可以使用request.files对象来处理文件上传。以下是一个简单的文件上传的示例:

from flask import Flask, request
from werkzeug.utils import secure_filename
import os

app = Flask(__name__)

# 定义文件上传的路径
UPLOAD_FOLDER = '/path/to/upload'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        # 检查是否有文件被上传
        if 'file' not in request.files:
            return '没有文件被上传'
        
        file = request.files['file']

        # 如果用户没有选择文件,浏览器可能会提交一个空文件,需要检查一下
        if file.filename == '':
            return '没有选择文件'
        
        # 文件检查通过后,保存文件
        if file:
            # 使用 Werkzeug 的 secure_filename 来确保文件名是安全的
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            return '文件已成功上传'
    
    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>
    '''

if __name__ == '__main__':
    app.run(debug=True)

在上述代码中,我们首先从flask和werkzeug.utils导入所需的模块。然后我们创建了一个Flask应用实例,并设置了文件上传路径。然后我们创建了一个路由/upload,这个路由接受GET和POST请求。

处理多个文件上传:

from flask import request
from werkzeug.utils import secure_filename

@app.route('/upload', methods=['POST'])
def upload_files():
    # `request.files` 是一个字典,包含了所有上传的文件
    for file_key in request.files:
        file = request.files[file_key]

        # 使用 `secure_filename` 函数来确保文件名是安全的
        filename = secure_filename(file.filename)

        # 保存文件到服务器
        file.save(os.path.join('uploads', filename))

    return 'Files uploaded successfully'

当我们接收到POST请求时,我们首先检查是否有文件在请求中。如果没有文件,我们就返回错误消息。如果有文件,我们使用Werkzeug的secure_filename函数来确保文件名是安全的,然后我们保存文件。

最后,当我们接收到GET请求时,我们返回一个HTML表单,用户可以通过这个表单来上传文件。

这里需要自己创建并指定文件上传的路径(在代码中为UPLOAD_FOLDER),并确保应用有权限写入此路径。

Werkzeug的secure_filename函数

werkzeug.utils.secure_filename 是一个安全功能,它确保用户上传的文件名不会导致安全问题。

这个函数首先检查并移除文件名中可能导致问题的特殊字符,例如路径分隔符(/\)和空格,从而防止目录遍历攻击(这种攻击通过在文件名中包含路径分隔符来试图访问不应该被访问的文件系统路径)。

例如,如果有人尝试上传一个名为"…/…/…/etc/passwd"的文件,secure_filename函数将会清理文件名,结果可能就变成了"etc_passwd",这样就防止了可能的安全问题。

另外,它还确保文件名仅包含ASCII字符,这样就避免了由于Unicode字符可能导致的一些编码问题。

下面是一个例子:

from werkzeug.utils import secure_filename

filename = secure_filename("../../etc/passwd")
print(filename)  # 输出: etc_passwd

所以,使用secure_filename函数是一个很好的实践,能确保用户上传的文件名不会导致文件系统或安全问题。

html文件上传例子

<!DOCTYPE html>
<html>
<body>

<h2>File Upload</h2>
<form action="http://localhost:5000/upload" method="post" enctype="multipart/form-data">
  Select file to upload:
  <input type="file" name="file" id="file">
  <input type="submit" value="Upload" name="submit">
</form>

</body>
</html>

在这个HTML代码中,我们创建了一个表单,其中包含一个文件输入元素和一个提交按钮。enctype="multipart/form-data"属性是必需的,如果你想要在表单中包含文件上传控件。

action="http://localhost:5000/upload"指定了表单提交后的处理URL。当你点击"Upload"按钮后,文件将被发送到该URL。请将该URL替换为你的Flask应用接受文件上传的实际URL。

在此示例中假设Flask应用正在本地运行,并监听5000端口,且你已经设置了一个名为/upload的路由来处理文件上传。

enctype=“multipart/form-data”

在HTML中,当你创建一个表单用于提交数据到服务器时,需要决定如何将这些数据编码和打包到HTTP请求中。这是由表单的 enctype 属性决定的。

enctype 属性决定了表单数据在提交时如何编码。它有三个可能的值:

  • application/x-www-form-urlencoded:这是默认值,所有的字符都会被编码(空格转换为 “+” 加号,特殊符号转换为 ASCII HEX 值)。这种编码方式适用于简单的表单,只包含文本字段。
  • multipart/form-data:这种编码方式不会对字符进行编码,这意味着你可以上传二进制文件。这是文件上传时必须使用的编码方式。
  • text/plain:这种编码方式会将空格转换为 “+” 加号,但不对特殊字符编码。这种编码方式不常用。

当你设置 enctype="multipart/form-data" 时,意味着你告诉浏览器应该使用 multipart/form-data 格式来编码表单数据。这个格式每个部分都是一个数据块,这些数据块可以包含二进制数据(例如文件内容),因此可以用来上传文件。每个部分都有自己的头部信息,描述了数据的类型、文件名等信息。这就是为什么你可以在一个表单中同时上传多个文件,每个文件作为请求主体中的一个部分。

当你使用 multipart/form-data 格式提交表单数据时,数据会被划分为多个部分或块。每一部分都代表了表单中的一个字段。例如,如果你的表单有两个文本字段和一个文件字段,那么数据就会被划分为三个部分。

每个部分都有自己的头部信息和主体内容。头部信息描述了这部分数据的类型和其他元数据。例如,头部信息可能包含Content-Disposition字段,该字段描述了这部分数据是一个表单字段,并提供了字段的名称和(如果这是一个文件字段的话)文件名。头部信息还可能包含Content-Type字段,该字段描述了数据的媒体类型(例如,文本、JPEG图片等)。

主体内容是这部分数据的实际内容。对于文本字段,主体内容就是用户输入的文本。对于文件字段,主体内容就是文件的二进制数据。

这是一个multipart/form-data请求的简化示例:

POST /upload HTTP/1.1
Host: example.com
Content-Type: multipart/form-data;boundary="boundary"

--boundary
Content-Disposition: form-data; name="text"

hello
--boundary
Content-Disposition: form-data; name="file"; filename="example.txt"
Content-Type: text/plain

Hello, World!
--boundary--

在这个示例中,数据被划分为两个部分。第一部分是一个名为"text"的文本字段,内容是"hello"。第二部分是一个名为"file"的文件字段,文件名是"example.txt",内容是"Hello, World!“。每个部分都由一个分界符(”–boundary")和自己的头部信息开始。请求以一个带有两个短划线的分界符(“–boundary–”)结束。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/53306.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Web3将自己写在合约中的代币添加到MetaMask中管理

上文 Web3带着大家根据ERC-20文档编写自己的第一个代币solidity智能合约 带着大家在智能合约中创建了一个自己的代币系统 我们可以在MetaMask中去导入 ganache环境下模拟出来的第一和第二个账号 我们这里 可以看到他们的 ETH 但看不到自己的代币符号 没关系 我们点击这下面的…

cicd实验

系列文章目录 文章目录 系列文章目录一、1.2. 二、安装并使用1.安装gitlab2.//Jenkins安装3. 总结 一、 1. 2. 二、安装并使用 需要三台服务器一台安装gitlab 192.168.169.10 第二台负责 安装jenkins 192.168.169.20 第三台是负责业务 192.168.169.30 1.安装gitlab yum in…

【前端知识】React 基础巩固(三十九)——React-Router的基本使用

React 基础巩固(三十九)——React-Router的基本使用 一、Router的基本使用 Router中包含了对路径改变的监听&#xff0c;并且会将相应的路径传递给子组件。 Router包括两个API&#xff1a; BrowserRouter使用history模式 HashRouter使用hash模式&#xff08;路径后面带有#号…

Linux进程概念(一)

文章目录 Linux进程概念查看进程杀死进程进程标识符 手动创建进程的方式fork函数创建进程 进程状态运行态阻塞态和挂起 Linux进程概念 前文我们了解了&#xff0c;进程的基本概念&#xff0c;在课本上被描述为&#xff0c;正在执行的程序&#xff0c;在linux内核上&#xff0c…

第一百一十六天学习记录:C++提高:STL-string(黑马教学视频)

string基本概念 string是C风格的字符串&#xff0c;而string本质上是一个类 string和char区别 1、char是一个指针 2、string是一个类&#xff0c;类内部封装了char*&#xff0c;管理这个字符串&#xff0c;是一个char型的容器。 特点&#xff1a; string类内部封装了很多成员方…

C++——STL容器之list链表的讲解

目录 一.list的介绍 二.list类成员函数的讲解 2.2迭代器 三.添加删除数据&#xff1a; 3.1添加&#xff1a; 3.2删除数据 四.排序及去重函数&#xff1a; 错误案例如下&#xff1a; 方法如下&#xff1a; 一.list的介绍 list列表是序列容器&#xff0c;允许在序列内的任何…

Git学习

一、Git工作流程 二、Git学习 1.获取本地仓库 要使用Git对我们的代码进行版本控制&#xff0c;首先需要获得本地仓库 在电脑的任意位置创建一个空目录(例如test)作为我们的本地Git仓库进入这个目录中&#xff0c;点击右键打开Git bash窗口执行命令git init如果创建成功后可在…

点云处理——terrasolid教程

加载terrasolid软件模块 3、通过microstation的utilities->mdl applications加载terrasolid四个模块,加载成功后将显示tscan和tphoto的主窗口&#xff0c;以及四个模块的主工具箱。 浏览点云 4、显示点云坐标信息(类&#xff0c; 航带号&#xff0c;GPS信息&#xff0c;东…

文心一言 VS 讯飞星火 VS chatgpt (67)-- 算法导论6.5 6题

文心一言 VS 讯飞星火 VS chatgpt &#xff08;67&#xff09;-- 算法导论6.5 6题 六、在 HEAP-INCREASE-KEY 的第 5 行的交换操作中&#xff0c;一般需要通过三次赋值来完成。想一想如何利用INSERTION-SORT 内循环部分的思想&#xff0c;只用一次赋值就完成这一交换操作? 文…

【Django+Vue】英文成绩管理平台--20230727

能够满足大部分核心需求&#xff08;标绿&#xff09;&#xff1a;报表部分应该比较难。 项目地址 前端编译 https://gitlab.com/m7840/toeic_vue_dist Vue源码 https://gitlab.com/m7840/toeic_vue Django源码 https://gitlab.com/m7840/toeic_python 项目架构 流程 …

嵌入式面试常见题目收藏(超总结)

​ 这篇文章来自很多博客主和其他网站的作者&#xff0c;如有侵权&#xff0c;联系必删 文章出处标注&#xff1a; https://blog.csdn.net/qq_44330858/article/details/128947083 ***如需PDF或者原稿可私信 *** ***如需PDF或者原稿可私信 *** ***如需PDF或者原稿可私信 *** 1.…

16位S912ZVML32F3MKH、S912ZVML31F1WKF、S912ZVML31F1MKH混合信号MCU,适用于汽车和工业电机控制应用。

S12 MagniV微控制器是易于使用且高度集成的混合信号MCU&#xff0c;非常适合用于汽车和工业应用。S12 MagniV MCU提供单芯片解决方案&#xff0c;是基于成熟的S12技术的完整系统级封装 (SiP) 解决方案&#xff0c;在整个产品组合内软件和工具都兼容。 S12 MagniV系统级封装 (S…

EP4CE6E22C8N Error: Can‘t recognize silicon ID for device 1

经过各种排查&#xff0c;发现是AS配置不对&#xff0c;仅供参考 工程 参考某处的工程画板配置的FPGA板子&#xff0c;用于学习入门FPGA。 烧录sof文件是正常的&#xff0c;并能正常运行。 但是烧录jic是failed&#xff0c;查看报错为&#xff1a;Error: Can’t recognize si…

【Maven】让maven更高效,优化maven构建项目速度

打开idea的setting&#xff0c;找到maven&#xff0c;设置它多线程数&#xff0c;重启后即可&#xff01; 我这里是8&#xff0c;你们可以随便设置。 如下图&#xff1a;

【高级数据结构】树状数组

目录 树状数组1 &#xff08;单点修改&#xff0c;区间查询&#xff09; 树状数组1 &#xff08;单点修改&#xff0c;区间查询&#xff09; 洛谷&#xff1a;树状数组1https://www.luogu.com.cn/problem/P3374 题目描述 如题&#xff0c;已知一个数列&#xff0c;你需要进行…

Vulnhub: shenron: 3靶机

kali&#xff1a;192.168.111.111 靶机&#xff1a;192.168.111.171 信息收集 端口扫描 nmap -A -sC -v -sV -T5 -p- --scripthttp-enum 192.168.111.171 修改hosts后访问目标80端口&#xff0c;发现是wordpress wpscan收集目标用户&#xff0c;爆破出密码&#xff1a;ilov…

前后端分离开发流程

1、介绍 在前后端分离开发中&#xff0c;前端负责用户界面和交互逻辑的实现&#xff0c;后端则处理业务逻辑和数据持久化。这种开发模式的优势在于前后端可以独立进行开发&#xff0c;提高了开发效率&#xff0c;并且使得前后端可以采用不同的技术栈来实现各自的功能。 2、开…

LabVIEW FPGA开发实时滑动摩擦系统

LabVIEW FPGA开发实时滑动摩擦系统 由于非线性摩擦效应的建模和补偿的固有困难&#xff0c;摩擦系统的运动控制已被广泛研究。最近&#xff0c;人们更加关注滑动动力学和滑动定位&#xff0c;作为传统机器人定位的低成本和更灵活的驱动替代方案。摩擦控制器设计和适当选择基础…

NodeJs后端项目使用docker打包部署

docker安装看之前的文章 默认已经安装好docker并且配置没有问题 拉取项目 https://gitee.com/coder-msc/docker-node 本地跑一个看看 pnpm install pnpm start 本地访问 http://localhost:1301/getname?name%E5%93%88%E5%88%A9%E6%B3%A2%E7%89%B9项目整个上传服务器 查看…

【Spring】Spring之循环依赖底层源码解析

什么是循环依赖 A依赖了B&#xff0c;B依赖了A。 示例&#xff1a; // A依赖了B class A{public B b; }// B依赖了A class B{public A a; }其实&#xff0c;循环依赖并不是问题&#xff0c;因为对象之间相互依赖是很正常的事情。示例&#xff1a; A a new A(); B b new B…