zoukankan      html  css  js  c++  java
  • 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;
                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("
    ")
                        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
    
    
    
  • 相关阅读:
    LiteOS基于Sensorhub的超声波模组移植
    了不起的 Deno:带你极速获取各大平台今日热榜
    vue+echarts+datav大屏数据展示及实现中国地图省市县下钻
    Vue3.x 从零开始(六)—— Router + Vuex + TypeScript 实战演练(下)
    Vue3.x 从零开始(五)—— Router + Vuex + TypeScript 实战演练(上)
    Vue 项目在 style 标签内使用全局 less 变量
    CPU:网卡老哥,你到底怎么工作的?
    主板上来了一个新邻居,CPU慌了!
    还不懂Docker?一个故事安排的明明白白!
    五分钟看懂抓包神技:DPDK
  • 原文地址:https://www.cnblogs.com/nyist-xsk/p/10184937.html
Copyright © 2011-2022 走看看