IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> Python脚本--Flask 文件上传功能(前后端分离) -> 正文阅读

[Python知识库]Python脚本--Flask 文件上传功能(前后端分离)

偶然在Java开发同事那里看到他们临时项目使用的一个文件上传页面,比我原来写的好看,并且支持拖拽上传、多个文件上传。但它使用Java提供服务,没法直接使用, 简单写了一个Python Flask的后端脚本。

前端页面如下:

?

目录结构:

? ? ? ? flask_file_upload

? ? ? ? ? -- static

? ? ? ? ? ? ? ?-- uploads

? ? ? ? ? ? ? ? ? ? -- 视频.mp4

? ? ? ? ? -- app.py

? ? ? ? UI_file_upload

? ? ? ? ? -- css

? ? ? ? ? ? ? -- style.css

? ? ? ? ? -- images

? ? ? ? ? -- scripts

? ? ? ? ? ? ?--?lang.zh-Hans.js

? ? ? ? ? ? ?--?transfer.js

? ? ? ? ? -- index.html

app.py :

# !usr/bin/python3
# -*- coding=utf-8 -*-
# @File : app.py
# @Time : 2021-07-06

import os
import json
from urllib.parse import quote, unquote
from gevent import monkey
from gevent.pywsgi import WSGIServer
from flask_cors import CORS, cross_origin
from werkzeug.utils import secure_filename
from flask import Flask, \
    Blueprint, \
    request, \
    jsonify, \
    make_response, \
    send_from_directory


monkey.patch_all() # 将python标准的io方法,都替换成gevent中的同名方法,遇到io阻塞gevent自动进行协程切换
app = Flask(__name__)
cors = CORS(app)
app.config['JSON_AS_ASCII'] = False  # 而json.dumps方法需要添加参数 ensure_ascii=False;避免显示中文乱码
# app.config['MAX_CONTENT_LENGTH'] = 1024 * 1024  # 设置上传文件大小

basepath = os.path.dirname(__file__)
UPLOAD_PATH = os.path.join(basepath, r'static\uploads')


# 解析文件大小并分配相应的单位
def allocateUnit(value):
    multiplyFactor = 0
    tokens = ["bytes", "KB", "MB", "GB", "TB"]
    while value > 1024:
        value /= 1024
        multiplyFactor += 1
    if multiplyFactor <= 4:
        tokensUnit = tokens[multiplyFactor]
    return "%s %s" % (round(value, 2), tokensUnit)


@app.route('/files/<filename>', methods=["GET", "POST"])
def get_image(filename):
    if request.method == 'GET':
        # filename = quote(filename, "utf-8")  # 若使用 secure_filename, 则必须转换
        response = make_response(send_from_directory(UPLOAD_PATH, filename, as_attachment=True))
        response.headers["Content-Disposition"] = "attachment; filename={}".format(
            filename.encode().decode('latin-1'))
        return response

    if request.method == 'POST':
        # filename = quote(filename, "utf-8")  # 若使用 secure_filename, 则必须转换
        file_path = os.path.join(UPLOAD_PATH, filename)
        os.remove(file_path)
        return jsonify({'data': {'code': 'Delete success !'}}), 200


@app.route('/files/', methods=['POST', 'GET'])
def upload():
    if request.method == 'GET':
        file_list = []
        for root, dirs, files in os.walk(UPLOAD_PATH):
            for f in files:
                f_dict = {}
                f_p = os.path.join(root, f)
                # f_size = round((((os.stat(f_p)).st_size)/1024)/1000, 2)
                f_size = allocateUnit((os.stat(f_p)).st_size)
                f_dict["name"] = unquote(f, "utf-8")
                f_dict["size"] = (f_size)
                file_list.append(f_dict)
        return json.dumps(file_list)

    if request.method == 'POST':
        f = dict(request.form)['fileName']  # f = 2022-03%E6%8A%80%E6%9C%AF%E7%A0%94%E5%8F%91%E4%B8%AD%E5%BF%83KPI%E8%80%83%E6%A0%B8%E8%A1%A8.xlsx
        f = unquote(f, "utf-8")  # Uri解码后:f = 2022-03技术研发中心KPI考核表.xlsx
        fname = request.files.get('newfile')

        # 当前文件所在路径; 由于secure_filename 会忽略中文(“2022-03技术研发中心KPI考核表.xlsx” 会被更改为 “2022-03KPI.xlsx”),弃用
        # upload_file_path = os.path.join(basepath, r'static\uploads', secure_filename(f))
        upload_file_path = os.path.join(basepath, r'static\uploads', f)

        # print(upload_file_path)  # D:\pythontest\98-test\981-flaskupload\static\uploads\2022-03技术研发中心KPI考核表.xlsx
        fname.save(upload_file_path)
        return jsonify({'data': {'code': 'success'}}), 200


if __name__ == '__main__':
    # 将 127.0.0.1 8800 修改为本机的 ip地址即可
    app.run(threaded=True, host="127.0.0.1", port=8800, debug=True)

?

transfer.js (server_add 按需改为后端服务器的地址):

$(function() {
	var isDragOver = false;
	
	var files = [];
    // server_add 按需改为后端服务器的地址
	var server_add = "http://127.0.0.1:8800/";
	var currentFileName;

	var uploadQueue = [];
	var currentQueueIndex = 0;
	var isUploading = false;
	var getProgressReties = 0;
	
	var html5Uploader = null;
	var items = {};
	
	function initPageStrings() {
		document.title = STRINGS.WIFI_TRANS_TITLE;
		$('.content_title').text(STRINGS.FILES_ON_DEVICE);
		$('.table_header .filename').text(STRINGS.FILENAME);
		$('.table_header .size').text(STRINGS.FILE_SIZE);
		$('.table_header .operate').text(STRINGS.FILE_OPER);
	}
    

lang.zh-Hans.js (Web页面显示的内容和标题,按需更改):?

????

var STRINGS = {};

STRINGS.WIFI_TRANS_TITLE = 'File Upload';
STRINGS.FILES_ON_DEVICE = '您设备上的文件列表';
STRINGS.FILENAME = '文件名';
STRINGS.FILE_SIZE = '大小';
STRINGS.FILE_OPER = '操作';
STRINGS.CONFIRM_DELETE_BOOK = '是否删除文件?';
STRINGS.DOWNLOAD_FILE = '下载文件';
STRINGS.DELETE_FILE = '删除文件';
STRINGS.USE_ONE_BROWSER = '无法上传文件,请勿使用多个浏览器窗口同时上传。';
STRINGS.UPLOAD_FAILED = '上传失败,请重新打开网络 并 刷新此页重新上传。';
STRINGS.UNSUPPORTED_FILE_TYPE = '请选择文件。';
STRINGS.FILE_IN_QUEUE = '文件已经在上传列队中。';
STRINGS.FILE_EXISTS = '文件已存在,请先删除再重新上传。';
STRINGS.YOU_CHOOSE = '您选择了';
STRINGS.CHOSEN_FILE_COUNT = '个文件,只能上传';
STRINGS.VALID_CHOSEN_FILE_COUNT = '个文件。\n请选择文件,文件名不能重复。';
STRINGS.CANCEL = '取消';
STRINGS.SELECT_YOUR_FILES = '请选择您要上传的文件';
STRINGS.SUPPORTED_FILE_TYPES = '支持MP4';
STRINGS.CANNOT_CONNECT_SERVER = '无法连接到服务器,请重新连接网络并刷新此页后重新上传。';
STRINGS.DRAG_TO_HERE = "拖拽到此处上传";
STRINGS.SELECT_BUTTON_LABLE1 = "选择文件";
STRINGS.SELECT_BUTTON_LABLE2 = "可同时上传多个文件";
STRINGS.SELECT_BUTTON_LABLE = "选择文件";
STRINGS.WIFI_AVAILABLE = "网络连接已启用";

STRINGS.FONT_WIFI_TRANS_TITLE = 'WFi 传字体';
STRINGS.FONT_CONFIRM_DELETE_BOOK = '是否删除字体?';
STRINGS.FONT_UNSUPPORTED_FILE_TYPE = '请选择您要上传的TTF或OTF字体文件。';
STRINGS.FONT_SUPPORTED_FILE_TYPES = '支持TTF和OTF';
STRINGS.FONT_VALID_CHOSEN_FILE_COUNT = '个文件。\n请选择TTF或OTF文件,文件名不能重复。';
STRINGS.FONT_FILE_EXISTS = '文件已存在。';
?

前端使用Nginx运行,后端Flask运行即可。

前端:

???????? 下载:https://wwz.lanzoul.com/ijaYH07vaf6f?密码:6wcu

?????????

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-07-21 21:30:58  更:2022-07-21 21:31:12 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 12:13:14-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码