Python Flask结合Ajax实现文件上传的完整指南

慢慢来
慢慢来
发布时间:2026-10-15| 4人浏览过
原创

本文详细解析如何在Python Flask框架中利用Ajax技术实现高效的文件上传功能。通过深入讲解FormData对象的使用、HTML表单enctype属性的配置以及JavaScript中的异步请求处理,提供了单文件与多文件上传的完整代码示例。内容涵盖Flask视图函数的文件接收逻辑及常见问题的解决方案,帮助开发者优化上传体验并避免页面刷新。

前言

JS

在使用传统的from表单提交时,浏览器会直接向服务器发送选中文件的完整内容,而不仅仅是文件名。这种方式虽然简单,但缺乏灵活性。

出于安全考虑,HTML规范规定file-upload元素不允许HTML作者或JavaScript程序员预设默认文件名。HTML的value属性对此类元素被忽略,且该属性为只读,这意味着只有用户手动输入或选择的文件名才会被提交。当用户选择或修改文件名时,file-upload元素会触发onchange事件句柄。

利用form表单提交会导致页面刷新,用户体验不佳,因此使用AJAX进行文件上传是一个更优的选择。但这需要我们手动组织通过POST请求发送的数据内容,主要涉及FormData对象的使用。

FormData对象允许我们组装一组用于XMLHttpRequest发送请求的键/值对。它可以更灵活、方便地发送表单数据,且可以独立于表单使用。如果将表单的编码类型设置为multipart/form-data,则通过FormData传输的数据格式与表单通过submit()方法传输的数据格式完全相同。—— MDN web docs

Form的enctype属性

enctype属性管理的是表单的MIME编码,它主要包含以下三种属性值:

值描述
application/x-www-form-urlencoded在发送前编码所有字符(默认)
multipart/form-data不对字符编码,用来制定传输数据的特殊类型,如mp3、jpg
text/plain纯文本传输

Input

value保存了用户指定的文件的名称
type=“file”设置input类型为file
multiple=“multiple”可多选,不设置为单选
accept=“…”设置可选文件的MIME_type。在设置之后点击选择文件按钮会默认显示符合设置的MIME_type的文件(存在兼容性)。具体的文件类型对应的MIME类型可以搜索到,这里列出我用到的类型:

MIME类型(更多直接百度,类型超乎你的想想)

文件类型MIME类型
.txttext/plain
.pdfapplication/pdf
.docapplication/msword
.docxapplication/vnd.openxmlformats-officedocument.wordprocessingml.document
.xlsapplication/vnd.ms-excel
.pptapplication/vnd.ms-powerpoint
.pptxapplication/vnd.openxmlformats-officedocument.presentationml.presentation

上传单个文件

html代码部分

<form   id="uploadForm"  method="post" enctype="multipart/form-data">
  <label  >上传电子书</label>
  <input type="file"  name="file" >
  <button  id="upload" type="button"  name="button" >上传</button>
  </br>
  </br>
  </br>
</form>

javascript代码部分

<script src="http://www.jq22.com/jquery/jquery-1.10.2.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/layer/3.5.1/layer.js "></script>
<script>
  $("#upload").click(function(){
  var formData = new FormData($('#uploadForm')[0]);
  $.ajax({
    type: 'post',
    url: "{{ url_for('.regression_report') }}", //上传文件的请求路径必须是绝对路劲
    data: formData,
    cache: false,
    processData: false,
    contentType: false,
    success:function(data){
      // 这里是访问成功时被自动执行的代码
      // 拆分返回值信息(具体返回什么东西就看视图函数中定义的json格式)
      status_ret = data.status;
      errmsg_ret = data.errmsg;
      layer.msg(errmsg_ret);
      switch (status_ret){
        case 0:
          setTimeout(function(){window.location.href = "{{ url_for('.regression_report') }}";},"2000");
          break
        default:
          setTimeout(function(){window.location.href = "{{ url_for('.regression_report') }}";},"2000");
          break
      }
    },
    error:function(jqXHR){
      // 这里是访问失败时被自动调用的代码
    }
  });
});
</script>

当你的页面样式比较多的时候,可能上述方法无法传入文件,下面这种方法比较强,推荐看看

<form class="info" method="post" enctype="multipart/form-data">
  <div class="form-group">
    <label>File upload</label>
    <input id="id_regression_html" type="file" name="regression_html" class="file-upload-default">
    <div class="input-group col-xs-12">
      <input type="text" class="form-control file-upload-info" disabled="" placeholder="Upload Regression.html">
      <span class="input-group-append">
        <button id="html_upload" class="file-upload-browse btn btn-gradient-primary" type="button">Html Upload</button>
      </span>
    </div>
  </div>
  <button id="id_ajax_submit" type="button" class="btn btn-gradient-primary mr-2">Submit</button>
</form>
<script src="https://cdn.bootcdn.net/ajax/libs/layer/3.5.1/layer.js "></script>
<script>
      $("#id_ajax_submit").click(function(){
      // var formData = new FormData($('#uploadForm')[0]);
      let formData = new FormData();
      let my_file = document.getElementById('id_regression_html');
      // @Param: <input name="regression_html">
      // @Param: myFile.file[0]为第一个文件(单选),多个文件(多选)则要循环添加
      formData.append('regression_html',my_file.files[0]);
  
        $.ajax({
            type: 'post',
            url: "{{ url_for('.regression_report') }}", //上传文件的请求路径必须是绝对路劲
            data: formData,
            cache: false,
            async: false,
            processData: false, //告诉jquery不要处理发送的数据
            contentType: false, //告诉jquery不要设置content-Type请求头
            success:function(data){
            // 这里是访问成功时被自动执行的代码
            // 拆分返回值信息(具体返回什么东西就看视图函数中定义的json格式)
            status_ret = data.status;
            errmsg_ret = data.errmsg;
            layer.msg(errmsg_ret);
            switch (status_ret){
                case 0:
                    setTimeout(function(){window.location.href = "{{ url_for('.regression_report') }}";},"2000");
                    break
                case 1:
                    setTimeout(function(){window.location.href = "{{ url_for('.regression_report') }}";},"2000");
                    break
                default:
                    setTimeout(function(){window.location.href = "{{ url_for('.regression_report') }}";},"2000");
                    break
                }
            },
            error:function(jqXHR){
              // 这里是访问失败时被自动调用的代码
            }
        });
    });
</script>

flask 视图函数部分

@admin_blu.route("/toolReg", methods=['GET', 'POST'])
def regression_report():
    if request.method == "GET":
        return render_template('index.html')
    elif request.method == "POST":
        # TODO: 获取设置
        # TODO: 获取文件
        f = request.files.get('file')
        if f and f.filename.__contains__('.html'):
            upload_path = os.path.join(current_app.root_path, 'static/upload/html', f.filename)            download_path = os.path.join(current_app.root_path, 'static/upload/html', 'xlsx')
            # TODO: 类实例化,同步执行
            f.save(upload_path)
            ret = {
                "status": 0,
                "errmsg": "上传成功"
            }
            return jsonify(ret)
        return redirect(url_for(".index.html"))

上传多个文件

html

<form id="uploadForm" enctype="multipart/form-data">
  <input type="file" name="file" multiple="multiple" />
</form>
<button id="btnUpload">上传文件</button>

js

<script>
  $("#btnUpload").on("click", function(){
  var formdata = new FormData($("#uploadForm")[0]);
  alert(formdata);
  $.ajax({
    type: "post",
    url: "/Attendance/UploadFile2/",//url地址
    contentType: false,
    cache: false,
    processData: false,
    data: formdata,
    success: function (data) {
      console.log(data);
    }
  });
});
</script>

出问题解决方案

//将formdata改用下面的方式试下
var formdata = new FormData();
var files = $("input[type='file']")[0].files;
for (var i = 0; i < files.length; i++) {
  formdata.append("file", files[i]);
}

到此这篇关于Python flask使用ajax上传文件的文章就介绍到这了,更多相关Python flask上传文件内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。