Python flask使用ajax上传文件的示例代码

作者:CDamogu 时间:2021-06-25 17:40:29 

前言

JS

为什么要用ajax来提交
在使用from提交时,浏览器会向服务器发送选中的文件的内容而不仅仅是发送文件名。

为安全起见,即file-upload 元素不允许 HTML 作者或 JavaScript 程序员指定一个默认的文件名。HTML value 属性被忽略,并且对于此类元素来说,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]);
}

来源:https://blog.csdn.net/qq_33704787/article/details/126003341

标签:Python,flask,ajax,上传文件
0
投稿

猜你喜欢

  • JavaScript判断浏览器运行环境的详细方法

    2024-04-22 12:53:28
  • python实现趣味图片字符化

    2022-01-22 15:29:35
  • python for循环赋值问题

    2023-01-26 05:56:32
  • 基于Python数据结构之递归与回溯搜索

    2022-02-27 01:40:33
  • Python中XlsxWriter模块简介与用法分析

    2022-12-29 15:10:57
  • ASP 游标参数详解(ASP记录集)第1/2页

    2011-04-08 11:04:00
  • Python中np.argmax()函数用法示例

    2021-06-17 23:47:09
  • IE6,IE7中定位相关的怪异问题

    2009-12-08 12:49:00
  • Python生成指定数量的优惠码实操内容

    2021-06-12 18:29:25
  • mysql insert语句操作实例讲解

    2024-01-15 12:12:24
  • Python实现简易版的Web服务器(推荐)

    2021-04-21 04:41:15
  • Python区块链客户端类开发教程

    2023-06-18 03:05:51
  • Python Django框架中表单的用法详解

    2021-11-06 04:24:41
  • jquery无法设置checkbox选中即没有变成选中状态

    2024-04-22 22:33:26
  • mysql中模糊查询的四种用法介绍

    2024-01-23 17:03:02
  • Python3.6简单反射操作示例

    2021-05-04 03:32:05
  • python如何读取bin文件并下发串口

    2021-12-21 17:09:21
  • 什么是gzip,人肉gzip?

    2008-11-20 13:01:00
  • Go语言调用Shell与可执行文件的实现

    2024-02-06 17:03:44
  • 9个Web设计中常见的可用性错误[译]

    2009-03-11 20:25:00
  • asp之家 网络编程 m.aspxhome.com