flask通过ajax实现文件上传

前端代码展示

<div class="modal fade" id="createResource" tabindex="-1" role="dialog" aria-labelledby="seeUserModalLabel">
        <div class="modal-dialog" role="document" style="max-width:450px;">
            <form action="" method="post" autocomplete="off" draggable="false">
                <div class="modal-content">
                    <div class="modal-header">
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
                                aria-hidden="true">&times;</span></button>
                        <h4 class="modal-title">添加音频资源</h4>
                    </div>
                    <div class="modal-body">
                        <table class="table" style="margin-bottom:0px;">
                            <thead>
                            <tr></tr>
                            </thead>
                            <tbody>
                            <div style="margin-bottom: 10px;"><input id="uploads-file" type="file" class="form-control" name="file-uploads" accept="audio/*"></div>
                            <tr>
                                <td wdith="20%">资源名:</td>
                                <td width="80%"><input type="text" value="" class="form-control" id="resource-name"
                                                       name="resource-name" maxlength="50" placeholder="请输入该资源名"
                                                       autocomplete="off"/></td>
                            </tr>
                            <tr>
                                <td wdith="20%">开始时间:</td>
                                <td width="80%">
                                    <input type="text" name="start-time" class="form-control form_datetime start-time" readonly placeholder="请选择开始播放时间..." required>
                                </td>
                            </tr>
                            <tr>
                                <td wdith="20%">结束时间:</td>
                                <td width="80%">
                                    <input type="text" name="end-time" class="form-control form_datetime end-time" readonly placeholder="请选择结束播放时间..." required>
                                </td>
                            </tr>
                            </tbody>
                            <tfoot>
                            <tr></tr>
                            </tfoot>
                        </table>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
                        <button id="uploadsFilesBtn" type="button" class="btn btn-primary">提交</button>
                    </div>
                </div>
            </form>
        </div>
    </div>

注意button的类型是type="button"

ajax请求代码展示

$('#uploadsFilesBtn').on('click', function () {
        let fileObj = document.getElementById("uploads-file").files[0];
        let filename = $('input[name="resource-name"]').val()
        let start_time = $(".start-time").val()
        let end_time = $(".end-time").val()
        if (typeof (fileObj) == "undefined" || fileObj.size <= 0) {
            toastr.error('未上传音频资源');
        } else if (filename === '' || isNull(filename)) {
            toastr.error('未填写音频资源名');
        } else if (start_time === undefined || start_time === '' || end_time === undefined || end_time === '') {
            toastr.error('音频资源播放时间未设置');
        } else {
            var formFile = new FormData();
            formFile.append("eid", {{ exam.id }});
            formFile.append("filename", filename);
            formFile.append("start_time", "start_time");
            formFile.append("end_time", "end_time");
            formFile.append("file", fileObj); //加入文件对象

            let data = formFile
            $.ajax({
                url: "{{ url_for('web.uploads_resource') }}",
                data: data,
                type: "POST",
                dataType: "json",
                cache: false,//上传文件无需缓存
                processData: false,//用于对data参数进行序列化处理 这里必须false
                contentType: false, //必须
                success: function (res) {
                    console.log(res)
                },
            })
        }
    });

后端接口获取数据实现保存

import os
import uuid

from flask import request, current_app
from flask_login import login_required
from werkzeug.utils import secure_filename
from app.web import web

@web.route('/resource/uploads', methods=['GET', 'POST'])
@login_required
def uploads_resource():
    form = request.form
    if request.method == 'POST':
        file = request.files.get('file')
        take_name = str(uuid.uuid4()) + '.' + file.filename.split('.')[1]
        filename = secure_filename(take_name)
        file.save(os.path.join(current_app.config['UPLOAD_FOLDER'], filename))
    return 'success'

其中,current_app.config['UPLOAD_FOLDER']是配置文件中声明的文件上传保存路径

secure_filename获取不到中文文件名

查看werkzeug.utils源码会发现文件匹配没法匹配到中文,也就获取不到中文文件名了

解决方法:
  1. 像我上面那样通过uuid生成一个随机字符串重写文件名,因为我会把文件路径保存到数据库里,所以不担心查找问题
  2. 使用第三方库(pypinyin),将中文名转换成拼音;也是重写文件名
  3. 修改源代码(不得已而为之),具体可以借鉴这篇文章
posted @ 2022-07-26 21:31  七夜魔手  阅读(7)  评论(0编辑  收藏  举报  来源