环境

python 3.6 你换成其他3x的版本也没关系

flask

项目很小,主要是演示一下使用flask接收页面上传的文件的方法。项目包含一个批量示范页面。

演示页面文件,为了方便演示。我把html,css和js写在一起了

演示页面 demo.html

body {

font-size: 14px;

}

.my_div {

min-height: 400px;

background-color: #f7f7f7;

display: flex;

flex-direction: column;

justify-content: center;

align-items: center;

}

.my_div .json_div {

min-width: 100%;

padding: 10px;

}

.my_div .json_div >.json_div_inner {

min-width: 100%;

min-height: 50px;

border: 1px solid #d3d3d3;

border-radius: 5px;

padding: 10px;

}

.my_div .json_div >.json_div_inner >li {

margin-left: 20px;

}

.my_div #my_progress {

width: 96%;

position: relative;

}

.my_div #my_progress >.my_per {

color: #ff7d7f;

position: absolute;

display: block;

width: 4em;

top: 1px;

left: 50%;

}

.my_div .my_bottom {

padding: 10px 10px 20px;

}

.my_div .my_bottom >#select_image {

display: none;

}

批量上传演示页

0%

选择

上传

function upload_progress(event, progress_cb){

/*

上传进度处理函数

:params event: 文件上传事的事件,

:params progress_cb: 回调函数,本函数会把上传完成的百分数当作地一个参数传入此回调函数.

默认情况下.会在控制台打印上传完成度. 注意,100并不代表服务端完整的接收到了文件.

只代表页面已经发送完了所有的文件内容.

*/

if (event.lengthComputable) {

var complete_percent = Math.round(event.loaded * 100 / event.total);

var handler = progress_cb?progress_cb: function(num){console.log(`上传完成度:${num}`)};

handler(complete_percent);

}else{}

}

function upload_complete(event, success_cb){

/*

上传文件success时的事件,只要服务器返回状态码200,就会执行本函数,并并不是代表服务器返回了正确的信息.

根据实际需要可以覆盖.

:params event: 文件上传事的事件,一般由XMLHttpRequest的upload的事件监听器来传递事件.

:params success_cb: 成功时的回调函数,

:return: nothing

*/

let str = event.target.responseText;

let handler = success_cb? success_cb: function(a){console.log(a);};

handler(str);

}

function upload_error(event, error_cb){

/*

上传文件失败时的事件,根据实际需要可以覆盖.

:params event: 文件上传事的事件,一般由XMLHttpRequest的upload的事件监听器来传递事件.

:params error_cb: 失败时的回调函数,

:return: nothing

*/

let handler = error_cb? error_cb: function(a){console.log(event);};

handler(event);

}

function batch_upload(options){

/*

批量上传文件. 不限制文件大小

options = {

files: 数据的序列,

url: str,

headers: 键值对对象,

success_cb: function,

error_cb: function,

progress_cb: function,

}

:params files: input标签的files

:params url: 上传的服务器url

:params headers: 放入header的参数,是键值对形式的字典,键名不要用下划线,因为那不符合规范

:params success_cb: 成功时的回调函数,会把服务器的返回信息作为第一个参数传入此回调函数.

:params error_cb: 失败时的回调函数,会把错误信息作为第一个参数传入此回调函数.

:params progress_cb: 上传时的返回上传进度的回调函数,会把页面上传文件的百分书作为第一个参数传入此回调函数..

:return: 不返回数据,由回调函数返回.

有关XMLHttpRequest对象的详细信息,请参考.

https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest

有关XMLHttpRequest.send方法的详细文档地址:

https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/send

*/

let files = options['files'];

let file_data = options['file_data'];

let url = options['url'];

let headers = options['headers'];

let success_cb = options['success_cb'];

let error_cb = options['error_cb'];

let progress_cb = options['progress_cb'];

let prog_func = function(event){upload_progress(event, progress_cb)}; // 进度的回调函数

let comp_func = function(event){upload_complete(event, success_cb)}; // 成功时的回调函数

let erro_func = function(event){upload_error(event, error_cb)}; // 失败时的回调函数

// 构造数据容器

let data = new FormData();

for(let file of files){

data.append(file.name, file);

}

// 新建一个请求对象

let req = new XMLHttpRequest();

// 添加事件监听器

req.upload.addEventListener("progress", prog_func, false);

req.addEventListener("load", comp_func, false);

req.addEventListener("error", erro_func, false);

req.addEventListener("abort", erro_func, false);

req.open("post", url);

// 必须在open之后才能给请求头赋值

if(headers){

/*

* 传送请求头信息,目前服务端还未做对应的处理.这只是与被给后来使用的.

* */

for(let k in headers){

req.setRequestHeader(k, headers[k]);

}

}

try{

req.send(data); // 404错误会直接在此抛出

}catch(e){

let handler = error_cb? error_cb: function(ms){console.log(ms);};

handler(e);

}

}

/*扩展函数注册区域*/

$.extend({

batch_upload: batch_upload // 批量上传文件,无尺寸限制

});

// 点击选择按钮的事件

$("#select_btn").click(function(){

$("#select_image").click();

});

let progress = function(per){

// 处理上传进度

console.log(`per is ${per}`);

$("#my_progress>.progress-bar").attr("style", `width: ${per}%;`).attr("aria-valuenow", `${per}`);

if(per > 52){

$(".my_per").css("color", "#fff");

}

$(".my_per").text(`${per}%`);

};

// 上传图片按钮事件

$("#select_image").change(function(){

let ul = $(".json_div_inner:first");

ul.empty();

let files = this.files;

for(let f of files){

ul.append(`

${f.name}`);

}

});

let call_back = function(){

$("#upload_btn, #select_btn").attr("disabled", false).removeClass("disabled");

alert("操作结束!");

};

// 上传图片模态框,提交按钮事件

$("#upload_btn").click(function(){

let $obj = $("#select_image");

let files = $obj[0].files;

let opts = {

"url": "/file/save",

"files": files,

"success_cb": call_back,

"error_cb": call_back,

"progress_cb": progress

};

$("#upload_btn, #select_btn").attr("disabled", true).addClass("disabled");

$.batch_upload(opts);

});

服务端的文件也很简单 server.py

# -*- coding: utf-8 -*-

from flask import Flask

from flask import render_template

from flask import request

import json

import os

app = Flask(__name__)

port = 7002

root_dir = os.path.dirname(os.path.realpath(__file__))

resource_dir = os.path.join(root_dir, 'resource')

@app.route("/")

def upload_demo():

"""上传页面"""

return render_template("upload_demo.html", page_title="批量上传")

@app.route("/file/", methods=['post', 'get'])

def file_func(action):

"""

:param action: 动作, save/get(保存/获取)

:return:

"""

mes = {"message": "success"}

if action == "save":

"""保存文件"""

if os.path.exists(resource_dir):

pass

else:

os.makedirs(resource_dir)

for key_name, file_storage in request.files.items():

if file_storage is not None:

file_name = file_storage.filename

file_storage.save(os.path.join(resource_dir, file_name))

file_storage.close()

elif action == "get":

"""获取文件/图片,未实现"""

pass

return json.dumps(mes)

if __name__ == '__main__':

app.run(host="0.0.0.0", port=port, debug=True, threaded=True)

项目的目录结构也很简单。

2018-09-27 15-40-54屏幕截图.png

python批量上传_python批量上传相关推荐

  1. python批量新建文件_python批量处理

    python opencv图像二值化批量处理 from skimage import data_dir,io,transform,color,filters import numpy as np im ...

  2. python添加图片水印_python 批量添加图片水印

    python程序,用来批量添加图片水印.输入一个文件夹.水印位置(左下角.底部中间.右下角).用户名(用户名是中文的),批量给文件夹里所有的jpg和png图片在指定位置添加水印. 水印内容是:用户名 ...

  3. python分片上传_python 分片上传大格式

    form-data类型 def multipart_producer(boundary, filename): """构建 multipart, 返回 yield, 实现 ...

  4. python批量裁剪图片_python批量剪切图片实现代码

    例子,python入门实例,python实现图片批量剪切. 代码: 代码示例: #!/usr/bin/python # www.# import os from PIL import Image #批 ...

  5. python通过qt5添加水印_Python 批量加水印就这么简单!

    工作的时候,尤其是自媒体,我们必备水印添加工具以保护我们的知识产权 ,网上有许多的在线/下载的水印添加工具,但他们或多或少都存在以下问题: 在线工具需要将图片上传到对方服务器,信息不安全. 很多工具不 ...

  6. python 爬取作品集_Python批量抓取站酷ZCOOL作品图片并归档

    前言 前几天,由于个人有需求,所以就要对站酷网一些类别下的作品的图片进行批量抓取,首先是采用的是NodeJs来写的,但是在运行的途中遇到很多的问题,所以后来就换成了Python,同时使用了多线程,使得 ...

  7. python批量导入图片_Python批量导入图片生成PowerPoint 2007+文件

    原标题:Python批量导入图片生成PowerPoint 2007+文件 说明:本文是"Python批量爬取微信公众号文章中的图片"的后续文章,用来把从公众号批量抓取的图片还原为P ...

  8. python怎么批量爬取图片_python批量爬取网络图片

    上篇通过python爬取了一篇网络小说,初步了解了爬虫的四步流程,本文稍微扩展一点,试着从网页中爬取出多个图片,具体来看看: 我们今天试着从下面图1的网页上将所有图片都爬取出来,放在一个指定的文件夹里 ...

  9. python怎么批量下载图片_python批量下载照片

    python批量下载照片 #!/usr/bin/python # _*_ coding: utf-8 _*_ ''' Created on 2018年8月22日 ''' # 导入包 import ur ...

最新文章

  1. debian10 简单的CA使用
  2. 2021年大数据ZooKeeper(四):ZooKeeper的shell操作
  3. 皮一皮:大型海王翻车现场...
  4. POJ 3481 Double Queue
  5. python3中map函数_python3中map()和reduce()函数
  6. 1077篇!ICCV2019接收结果公布,你中了吗?(附7篇论文链接,含Oral)
  7. hexeditor 复制二进制值_MySQL复制全解析 Part 6 MySQL GTID 生命周期
  8. 2008是中国的奥运年
  9. 连锁行业信息化的现状与问题
  10. mac电脑安装mysql
  11. android 改变音乐格式,音乐速度变更器app-音乐速度变更器下载v9.4.4-hu安卓版-西西软件下载...
  12. 路由器配置出现192.168.1.0 overlaps with Vlan2的解决方案
  13. 华三交换机如何进入配置_华三交换机配置方法及操作案例
  14. 游戏开挂的罪与非罪——从“王者荣耀外挂案”说起
  15. MES管理系统生产调度管理功能的作用介绍
  16. python如何计算累乘和累加
  17. 中金公司、 汇金公司、 中投公司有什么联系和区别?
  18. 数据结构之树的概念以及结构
  19. 计蒜客 红与黑 dfs
  20. 互联网用户账号信息真实性认证(阿里云身份信息实名认证API接口服务)

热门文章

  1. oracle 差分备份,Oracle数据库RMAN备份与恢复:备份与恢复(手机搬家)
  2. python课件_python展示ppt
  3. 在VScode搭建Vue环境
  4. 如何恢复手机误删除照片
  5. Trends in Neurosciences:基于信息的无创经颅脑刺激方法
  6. ​国务院机构改革方案的学习
  7. 抖音直播间没流量怎么办 如何提高人气?
  8. spin lock irqrestore中为什么先开中断后开抢占
  9. 情态动词 can/could
  10. can和could的用法_2019初中英语情态动词之can和could