Django之上传文件

还记得Ajax的三种请求发送方式吗?(原生Ajax,jquery,伪Ajax)

上传文件也是一样的,同样是这三种方法。

 

首先先创建一个表单,用于上传文件

<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .upload{
            position: absolute;
            display: inline-block;
            background-color: darkcyan;
            text-align: center;
            line-height: 35px;
            top: 0px;
            right: 0px;
            left: 0px;
            bottom: 0px;
            z-index:10;
        }
        .file{
            position: absolute;
            opacity: 0;
            z-index: 20;
              top: 0px;
            right: 0px;
            left: 0px;
            bottom: 0px;
        }
    </style>
</head>
<body>
    <div style="width: 70px;height: 35px; background-color: cadetblue; position: relative;">
        <input class="file" type="file" id="f" name="file">
        <a class="upload">上传</a>
    </div>
    <input type="button" value="提交XHR" onclick="xhrSubmit()"/>
    <input type="button" value="提交ajax" onclick="jqSubmit()"/>
    <div id="ifbd">
        <form action="/upload_file/" method="POST" enctype="multipart/form-data" target="ifml">
            <iframe id="ifram" name="ifml"></iframe>
            <input type="file" name="file"/>
            <input type="submit" value="on" onclick="iframeSubmit()"/>
        </form>
    </div>
</body>
View Code

代码中为了界面美观而加了一些样式,可以不必理会。

注意代码中的submit标签分别对应不同的onclick事件,分别对应着不同的请求方法,代码如下。

接下来我们就可以选择不同的方法来发送表单:

1.原生Ajax:

  基于XMLHttpResponse(xhr)发送请求

<script>
        function xhrSubmit() {
            //jquery对象【0】索引代表dom对象
            var file_obj=$('#f')[0].files[0];//文件就这样获取
            var formdata=new FormData();
            formdata.append('file',file_obj);//add方法,前面是key,后面是value,可以加普通字符串,也可以是特殊对象
            formdata.append('username','root');
            var xhr=new XMLHttpRequest();
            xhr.open('POST','/upload_file/',true);
            xhr.onreadystatechange=function () {
                if(xhr.readyState==4){
                    var obj=JSON.parse(xhr.responseText);
                    console.log(obj.data);
                    var tag=document.createElement('img');
                    tag.src='/'+obj.data;
                    $("#preview").append(tag);
                }
            };
            xhr.send(formdata)
        }
</script>

2.jQuery:

  通过jQuery中的Ajax方法来发送,本质上和xhr是一样的,只不过是jQuery对其做了封装

<script>
    function jqSubmit() {
            var file_obj=$('#f')[0].files[0];//文件就这样获取
            var formdata=new FormData();
            formdata.append('file',file_obj);//add方法,前面是key,后面是value,可以加普通字符串,也可以是特殊对象
            formdata.append('username','root');
            $.ajax({
                url:'/upload_file/',
                type:'POST',
                data:formdata,
                //这里需要加两个参数来做特殊处理
                processData:false,
                contentType:false,
                success:function (arg,a1,a2) {
                    console.log(arg)
                    console.log(a1)
                    console.log(a2)
                }
            })
        }
</script>

3.iframe方式提交(重要!)

<script>
    function iframeSubmit() {
            $('#ifram').load(function () {
                $('#preview').empty();
                var text=$('#ifram').contents().find('body').text();
                var obj=JSON.parse(text);
                console.log(obj);
                var tag=document.createElement('img');
                tag.src='/'+obj.data;
                $('#preview').append(tag);
            })
        }
</script>

为什么这种方式是重要的?因为那些坑爹的IE浏览器会对xhr产生抗拒,也就是兼容问题,但是这种方式几乎所有的浏览器都适用,几乎没有什么兼容性的问题,

因此上传文件的话iframe方式推荐首选。

最后,到了我们的后台接受文件的时候了,虽然前端提交的时候花样挺多,但不管你用那种方式,我后端服务器也只管收就是了

def upload(request):
    return render(request,'upload.html')

def upload_file(request):
    import json,os
    file=request.FILES.get('file')
    upload_path=os.path.join('static/upload',file.name)
    with open(upload_path,'wb') as wenjian:
        for i in file.chunks():
            wenjian.write(i)
    ret={'code':True,'data':upload_path}
    dic={
        'error':0,
        'url':upload_path,
        'messige':'invalid...'
    }
    print(json.dumps(ret))
    return HttpResponse(json.dumps(dic))

这里是将接受过来的文件存到了static/upload文件中,并以原文件命名:

upload_path=os.path.join('static/upload',file.name)

这样就成功的将文件上传至服务器端了。

 

  

posted @ 2017-11-06 21:26  月夜夕烧雾雨  阅读(273)  评论(0编辑  收藏  举报