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>
代码中为了界面美观而加了一些样式,可以不必理会。
注意代码中的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)
这样就成功的将文件上传至服务器端了。