以上传图片为列, 提交图片文件后能在不刷新页面的前提下显示图片
首先写出一个简单的提交文件的页面:
1 <h>文件上传</h> 2 选择文件<input type="file" name="fileName" id="img"> 3 <input type="button" value="提交" onclick="func1()"> 4 <input type="button" value="提交" onclick="func2()"> 5 6 7 <div id="imgs"> 8 {% for i in path %} 9 <img style=" 200px;height: 150px" src="{{ i.filePath }}" alt=""> 10 {% endfor %} 11 </div>
方法一:原生XMLHttpResponse对象+FormData
onclick func1()事件函数中加入提交方式:
1 function func1() { 2 var dic=new FormData();//创建FromData对象 3 dic.append("fileName",document.getElementById("img").files[0]);//对象可以存储键值对,类似于python中的字典,这里的值就是文件的内容,注意.files[0],取第一个内容 4 var xmlhttp = new XMLHttpRequest();//创建XMLHttpresponse对象 5 xmlhttp.open('post',"/mmm/upload/",true);//提交方式和提交路径 6 xmlhttp.send(dic);//发送数据 7 //先去看后台处理.... 8 xmlhttp.onreadystatechange=function () {//回调函数 9 if (xmlhttp.readyState==4){//判断返回成功 10 var obj=JSON.parse(xmlhttp.responseText)//后台发会的是json字符串,反序列 11 //这里是创建一个img标签,src=后台返回的路径,就可以在页面上直接显示图片了 12 if (obj.state){ 13 var img=document.createElement("img") 14 img.src="/"+obj.path 15 document.getElementById("imgs").appendChild(img) 16 } 17 } 18 } 19 }
后台:
1 def upload(req): 2 #如果是GET方式,就将数据库中的文件的路径返回到页面 3 if req.method=="GET": 4 file=models.upLoadFile.objects.all().values("filePath") 5 return render(req,"upload.html",{"path":file}) 6 #post方式处理 7 else: 8 obj=req.FILES.get("fileName")#获取前段发来的数据 9 import os 10 filePath=os.path.join("static",obj.name)#拼接路 11 #将前段发来的数据路径和名字存储到数据库 12 models.upLoadFile.objects.create(**{ 13 "fileName":obj.name, 14 "filePath":filePath 15 }) 16 #保存文件 17 f = open(filePath,"wb") 18 for i in obj.chunks():#发过来的文件对象是一块一块的,需要chunks()循环拼接 19 f.write(i) 20 f.close() 21 #返回给前段的数据,包括状态和路径 22 ret={"state":True,"path":filePath} 23 import json 24 return HttpResponse(json.dumps(ret))#由于是XMLHttpResponse,所以这里返回的是字符串,用json序列化
方法二:Ajax+FormData:
onclick func2()事件函数中加入提交方式:
1 function func2() { 2 //创建FormData 3 var dic=new FormData(); 4 dic.append("fileName",document.getElementById("img").files[0]); 5 //Ajax 6 $.ajax({ 7 url:"/mmm/upload/",//路径 8 type:"POST",//提交方式 9 data:dic,//提交的数据,FormData就可以承载文件数据 10 dataType:"JSON",//返回数据类型 11 processData:false,//Ajax默认会设置请求头,设置数据,这里就是告诉Jquery不要去设置,数据才会简单的被获取 12 contentType:false, 13 success:function (ret) {//回调函数 14 if (ret.state){ 15 var img=document.createElement("img") 16 img.src="/"+ret.path 17 $("#imgs").append(img) 18 } 19 } 20 }) 21 22 }
后台内容和方法一相同.
方式三:form表单+iframe伪造Ajax发送请求
因为FormData在低版本的浏览器不兼容
写出form表单+iframe:
后台代码和方法一方法二相同.
<form action="/mmm/upload/" method="post" enctype="multipart/form-data" target="ifr"><!--enctype为不编码 ,target目标提交到iframe标签--> <iframe id="ifr" name="ifr" onload="func3()"></iframe> <!--给iframe绑定一个onload事件,每次提交数据,iframe刷新完成执行--> <input type="file" name="fafafa"> <input type="submit" value="提交"> </form>
onload函数代码:
function func3(){ var ret=$("#ifr").contents().find("body").text()//iframe会在html里面嵌入html,并且获取到的数据保存在body里面,这里想要获取到iframe得到的数据就需要加上contents(),然后find到body ret=JSON.parse(ret)//反序列 //同方法一和方法二,创建img标签然后加入src,再添加到页面中 if (ret.state){ var img=document.createElement("img") img.src="/"+ret.path $("#imgs").append(img) } }