python django + js 使用ajax进行文件上传并获取上传进度案例

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        #progress{
            height:10px;
            width:500px;
            border: 1px solid gold;
            position: relative;
            border-radius: 5px;
        }
        #progress .progress-item{
            height:100%;
            position: absolute;
            left:0;
            top:0;
            background: chartreuse;
            border-radius: 5px;
            transition: width .3s linear;
        }
    </style>
</head>
<body>
<p style="color: blue;">上传文件:<br></p>
                <input type="file" id="file"><br>

                <p style="color: blue;">文件上传进度:<br></p>
                <div id="progress">
                    <div class="progress-item"></div>
                </div>

                <p style="color: blue;">文件上传状态:<br></p>
                <span id="callback" style="color: red;"></span>
</body>
<script>
    //首先监听input框的变动,选中一个新的文件会触发change事件
        document.querySelector("#file").addEventListener("change",function () {
            //获取到选中的文件
            var file = document.querySelector("#file").files[0];
            //创建formdata对象
            var formdata = new FormData();
            formdata.append("file",file); // 后台接收"file"字段
            //创建xhr,使用ajax进行文件上传
            var xhr = new XMLHttpRequest();
            xhr.open("post","/system/upload/");
            //回调
            xhr.onreadystatechange = function () {
                if (xhr.status==200){
                    document.querySelector("#callback").innerText = xhr.responseText;
                }else{
                }
            }
            //获取上传的进度
            xhr.upload.onprogress = function (event) {
                if(event.lengthComputable){
                    var percent = event.loaded/event.total *100;
                    document.querySelector("#progress .progress-item").style.width = percent+"%";
                }
            }
            //将formdata上传
            xhr.send(formdata);
    });
</script>
</html>

后端代码

def upload_files(request):
    if request.method == 'POST':
        try:
            get_file = request.FILES.get('file')
            if get_file is not None:
                # print type(get_file) # <class 'django.core.files.uploadedfile.InMemoryUploadedFile'>
                # print get_file.read()
                for con in get_file.readlines():
                    line = con.strip("\n")
                    if line.startswith("#"):
                        pass
                    else:
                        print line
                return HttpResponse("success!")
            else:
                print u"文件对象是None"
                return HttpResponse("false!")
        except Exception, e:
            print e
            return HttpResponse("false!")

后面的几种方法没试:

方式一:

通过form表单提交到后台

前端:


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/upload/" method="post" enctype="multipart/form-data">
        <input type="file" name="fafafa">
        <input type="submit">
    </form>
</body>
</html>


Django 后端:


def upload(request):
    if request.method == 'POST':# 获取对象
        obj = request.FILES.get('fafafa')
        import os
    # 上传文件的文件名 
    print(obj.name)        f = open(os.path.join(BASE_DIR, 'static', 'pic', obj.name), 'wb')
        for chunk in obj.chunks():
            f.write(chunk)
        f.close()
        return  HttpResponse('OK')
    return render(request, 'upload/upload.html')

方式二:

通过ajax提交

前端

<div>
        <input type="file" name="file" id="file_upload">
        <input type="button" value="上传" onclick="FileUpload()">
</div>
JS:


<script src="/static/js/jquery-3.2.1.min.js"></script>
<script>
    function FileUpload() {
            var form_data = new FormData();
            var file_info =$( '#file_upload')[0].files[0];
            form_data.append('file',file_info);
            //if(file_info==undefined)暂且不许要判断是否有附件
                //alert('你没有选择任何文件');
                //return false
            $.ajax({
                url:'/upload_ajax/',
                type:'POST',
                data: form_data,
                processData: false,  // tell jquery not to process the data
                contentType: false, // tell jquery not to set contentType
                success: function(callback) {

                    console.log('ok')
                }
            });

            }</script>

Django 后端:


def upload_ajax(request):
    if request.method == 'POST':
        file_obj = request.FILES.get('file')
        import os
        f = open(os.path.join(BASE_DIR, 'static', 'pic', file_obj.name), 'wb')
        print(file_obj,type(file_obj))
        for chunk in file_obj.chunks():
            f.write(chunk)
        f.close()
        print('11111')
        return HttpResponse('OK')

注意:

前台发送ajax请求时:

processData: false,  // tell jquery not to process the data
contentType: false, // tell jquery not to set contentType
必须设置


方式三:
通过iframe标签提交
前端:
   <div>
        <form id="my_form" name="form" action="/upload_iframe/" method="POST" enctype="multipart/form-data">
            <input type="text" name="user">
            <input type="password" name="password">
            <input type="file" name="file">
            <input type="button" value="upload"  onclick="UploadFile()">
        </form>
        <iframe id='my_iframe' name='my_iframe' src="" class="hide"></iframe>
    </div>

JS:


    function UploadFile() {
        document.getElementById('my_iframe').onload = Testt;
        document.getElementById('my_form').target = 'my_iframe';
        document.getElementById('my_form').submit();
    }
    function Testt(ths){
            var t = $("#my_iframe").contents().find("body").text();
            console.log(t);
        }

Django 后端:


def upload_iframe(request):
    if request.method == 'POST':
        print(request.POST.get('user', None))
        print(request.POST.get('password', None))
        file_obj = request.FILES.get('file')
        import os
        f = open(os.path.join(BASE_DIR, 'static', 'pic', file_obj.name), 'wb')
        print(file_obj,type(file_obj))
        for chunk in file_obj.chunks():
            f.write(chunk)
        f.close()
        print('11111')
        return HttpResponse('OK')

以上是文件上传的三种方式,在Tornado种也可以使用。

扩展:

在前段提交的时候 可以存在 checkbox 标签, 在Django中对于这种标签在后台获取值时用:

  request.POST.getlist('favor', None) checkbox

其它

request.POST.get('favor', None)  checkbox


posted @ 2018-12-27 14:49  xushukui  阅读(918)  评论(0编辑  收藏  举报