zoukankan      html  css  js  c++  java
  • Python菜鸟之路:Django 文件上传的几种方式

    方式一:通过form表单中,html input 标签的“file”完成

    # 前端代码uoload.html
        <form method="post" action="/upload/" enctype="multipart/form-data">
            <input id="user" type="text" name="user" />
            <input id='img' type="file" name="img" />
            <input type="submit" />
        </form>
    
    # 后端代码
    def upload(request):
        if request.method == 'POST':
            ret = {'status': False, 'data': None, 'error': None}
            try:
                user = request.POST.get('user')
                img = request.FILES.get('img')
                f = open(os.path.join('static', img.name), 'wb')
                for chunk in img.chunks(chunk_size=1024):
                    f.write(chunk)
                ret['status'] = True
                ret['data'] = os.path.join('static', img.name)
            except Exception as e:
                ret['error'] = e
            finally:
                f.close()
                return HttpResponse(json.dumps(ret))
        return render(request, 'upload.html')
    

    方法二:利用XmlHttpRequest对象,发送原生的Ajax请求

        (这种方法不能发送文件,需要依赖另外一个对象FormData)

     1 # 方法
     2 a. void open(String method,String url,Boolen async)
     3    用于创建请求
     4     
     5    参数:
     6        method: 请求方式(字符串类型),如:POST、GET、DELETE...
     7        url:    要请求的地址(字符串类型)
     8        async:  是否异步(布尔类型)
     9  
    10 b. void send(String body)
    11     用于发送请求
    12  
    13     参数:
    14         body: 要发送的数据(字符串类型)
    15  
    16 c. void setRequestHeader(String header,String value)
    17     用于设置请求头
    18  
    19     参数:
    20         header: 请求头的key(字符串类型)
    21         vlaue:  请求头的value(字符串类型)
    22  
    23 d. String getAllResponseHeaders()
    24     获取所有响应头
    25  
    26     返回值:
    27         响应头数据(字符串类型)
    28  
    29 e. String getResponseHeader(String header)
    30     获取响应头中指定header的值
    31  
    32     参数:
    33         header: 响应头的key(字符串类型)
    34  
    35     返回值:
    36         响应头中指定的header对应的值
    37  
    38 f. void abort()
    39  
    40     终止请求
    41 
    42 # 属性
    43 a. Number readyState
    44    状态值(整数)
    45  
    46    详细:
    47       0-未初始化,尚未调用open()方法;
    48       1-启动,调用了open()方法,未调用send()方法;
    49       2-发送,已经调用了send()方法,未接收到响应;
    50       3-接收,已经接收到部分响应数据;
    51       4-完成,已经接收到全部响应数据;
    52  
    53 b. Function onreadystatechange
    54    当readyState的值改变时自动触发执行其对应的函数(回调函数)
    55  
    56 c. String responseText
    57    服务器返回的数据(字符串类型)
    58  
    59 d. XmlDocument responseXML
    60    服务器返回的数据(Xml对象)
    61  
    62 e. Number states
    63    状态码(整数),如:200、404...
    64  
    65 f. String statesText
    66    状态文本(字符串),如:OK、NotFound...
    XmlHttpRequest对象的主要属性和方法
    <input type="button" value="XMLHttpRequest按钮" onclick="XHRAjax();">
    
    <script>
            function XHRAjax() {
                var xhr = new XMLHttpRequest();
                xhr.onreadystatechange = function () { # 回调函数--每当请求变化时,都会被触发,比如:创建、open、send、recv等。
                    if(xhr.readyState == 4){   # 仅当服务器数据全部返回时触发
                        var data = xhr.responseText;
                        console.log(data)
                    }
                };
                // GET请求
                // xhr.open('GET', '/xhr_ajax?p=123');
                // xhr.send();
                // POST请求
                xhr.open('POST', '/xhr_ajax/');  # 这里的URL必须加斜杠结尾。 发送post请求的时候必须携带请求头
                xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8');
                // 发送请求
                xhr.send('n1=1;n2=2;');
            };
    </script>
    
    def ajax(request):
        import time
        current_time = time.time()
        return render(request, 'ajax.html', {'current_time': current_time})
    

      上述的内容,已经可以完成原生ajax的发送。 如果需要发送文件,则需要借助于FormData对象.下边介绍一下FormData的简单用法

    # 前端代码
    
    <input type="button" value="XMLHttpRequest-FormData按钮" onclick="XHRAjaxForm();">
    
    # 后端代码: 基于FormData对象发送请求
    function XHRAjaxForm() {
                var xhr = new XMLHttpRequest();
                xhr.onreadystatechange = function () {
                    if(xhr.readyState == 4){
                        var data = xhr.responseText;
                        console.log(data)
                    }
                };
                xhr.open('POST', '/xhr_ajax/');
                // 发送请求
                var form = new FormData();  # 创建FormData对象
                form.append('user', 'alex');
                form.append('pwd', '123');
                xhr.send(form);
            };
    

      上面的例子,简单的介绍了FormData的用法 。下边的案例介绍如何使用formdate对象来上传文件

    # 前端部分
    <a onclick="uploadfile1();" style="cursor: pointer; display: inline-block;background-color: aqua">XMLHttpRequet上传</a>
    
    # JS部分
    <script>
          function uploadfile1() {
                var form = new FormData();
                form.append('user', document.getElementById('user').value);
    
                var fileobj = document.getElementById('img').files[0];
                form.append('img', fileobj);
    
                var xhr = new XMLHttpRequest();
                xhr.onreadystatechange = function () {
                    if(xhr.readyState == 4){
                        var data = xhr.responseText;
                        console.log(data)
                    }
                };
                xhr.open('post', '/upload/', true)
                xhr.send(form);
            }
    </script>
    

    方法三:利用JQuery Ajax + FormData进行文件上传

      Jquery转换为dom对象:$("#img")[0].files[0];   其中$("#img")是jquery对象, $("#img")[0]是dom对象

    <a onclick="uploadFile2();" style="cursor: pointer; display: inline-block;background-color: aqua">JQuery-Ajax上传</a>
    
    <script>
    
            function uploadFile2() {
                var fileobj = $("#img")[0].files[0];
                console.log(fileobj);
                var form = new FormData();
                form.append("img", fileobj);
                form.append("uesr", 'alex');
                $.ajax({
                    type: 'POST',
                    url: '/upload/',
                    data: form,
                    processData: false, # 告诉jquery要传输data对象
                    contentType: false,   # 告诉jquery不需要增加请求头对于contentType的设置
                    success: function (arg) {
                        console.log(arg)
                    }
                })
            }
    </script>
    

    方法四:基于Iframe 实现伪Ajax 上传文件

    <a onclick="uploadFile3();" style="cursor: pointer; display: inline-block;background-color: aqua">IFrame上传</a>
    
    
    
    <script>
            function uploadFile3() {
                // target 是个name的属性值,而不是id
                $("#container").find('img').remove();
                document.getElementById("my_iframe").onload = callback;
                document.getElementById('fo').target = 'my_iframe';
                document.getElementById('fo').submit();
            }
            function callback() {
                var t = $('#my_iframe').contents().find('body').text();
                var json_data = JSON.parse(t);
                console.log(json_data);
                if(json_data.status){
                    // 上传成功
                    var tag = document.createElement('img');
                    tag.src = "/" + json_data.data;
                    tag.className = 'img';
                    $('#container').append(tag);
    
                }else{
                    // 上传失败
                    console.log(status.error);
                }
    
            }
    </script>
    

      不是所有的浏览器都可以兼容FormData对象。为了兼容性,引出iframe 的用法。

       iframe可以建立一个通道发送请求,利用iframe局部刷新的特性实现目标。

    # 前端代码
    <iframe name="my_iframe" style="display: none;" src=""></iframe>
    # 这里使用的是name标签,和id标签无关
    
    
    <a onclick="uploadFile3();" style="cursor: pointer; display: inline-block;background-color: aqua">IFrame上传</a>
    
    <div id="container"></div>
    
        <script>
            function uploadFile3() {
                // target 是个name的属性值,而不是id
                $("#container").find('img').remove();
                document.getElementById("my_iframe").onload = callback; # 通过js手动绑定一个事件
                document.getElementById('fo').target = 'my_iframe';   # 这里target对应的是一个iframe 的name属性
                document.getElementById('fo').submit();
            }
            function callback() {
                var t = $('#my_iframe').contents().find('body').text();
                var json_data = JSON.parse(t);
                console.log(json_data);
                if(json_data.status){  
                    // 上传成功
                     var tag = document.createElement('img');
                    tag.src = "/" + json_data.data;
                    tag.className = 'img';
                    $('#container').append(tag);
    
                }else{
                    // 上传失败
                    console.log(status.error);
                }
    
            }
    
    </script>
    

      

      

      

  • 相关阅读:
    C#注释含义(XML注释)标签及其含义(二)
    Apache开启伪静态[转]
    C#注释含义(XML注释)标签及其含义(一)
    [转]终结PHP中文乱码的问题
    Symfony框架百科/项目实战/指南/教程
    第一次用Office2007写博客
    prototype.js是什么?
    优秀网站源码 集合
    Pager 精简的分页控件
    Validator.js 很好用的客户端表单验证
  • 原文地址:https://www.cnblogs.com/jishuweiwang/p/6140132.html
Copyright © 2011-2022 走看看