web页面 之 图片上传
关于图片上传,在web领域这是个经典问题之一!任何网站都需要牵扯到图片上传保存的问题!
关于图片上传,存储的方式有两种,一种直接上传到服务器再把路径返回给客户端然后显示,另一个是直接在客户端本地显示,上传的图片是从本机的内存中读取的!这两种的最大区别就是:减小服务端的压力!增加用户的友好性体验!废话不多说,直接上代码:
第一种:form表单+iframe标签(兼容所有浏览器的Bug组合,注意点:图片会先上传在服务端保存然后在客户端显示,这会给服务器带来压力,不过没别的办法!上传存储时先存在临时文件,用户确认之后,再放在正式文件中)
HTML: <form action="/up_img/" method="POST" target="ifr" enctype="multipart/form-data" id="f2"> {% csrf_token %} <iframe name="ifr" id="ifr" style="display: none"> </iframe> <div class="form-group"> <label for="inputPassword3" class="col-sm-2 control-label"></label> <div class="col-sm-6"> <div style="z-index: 600;position: relative"> <img style="width: 80px;height: 80px;margin-top: -60%;margin-left: -100%" src="" id="show_img"> </div> <div style="z-index: 800;position: relative;opacity: 0"> <input type="file" style="width: 80px;height: 80px;margin-top: -200%;margin-left: -100%" id="up-img" name="avatar"> </div> </div> </form> js: <script type="text/javascript" src="/static/jquery-3.2.1.js"></script> <script> $('#up-img').change(function () { document.getElementById("ifr").onload=loadIframe; $('#f2')[0].submit() }); function loadIframe() { var content = document.getElementById('ifr').contentWindow.document.body.innerText; $('#show_img').attr('src',content); $('#id_avatar').val(content) } $('#img-code').click(function () { $(this).attr('src',$(this).attr('src')+'?') }) </script> views: #头像上传 def up_img(request): if request.method == 'GET': return HttpResponse('o12!') else: file_obj = request.FILES.get('avatar') # 取文件时,需以FILES获取文件数据 file_path = ('static/img/' + file_obj.name) f = open(file_path, 'wb') # 以字节方式打开空文件,拼接文件路径 for chunk in file_obj.chunks(): f.write(chunk) f.close() return HttpResponse(file_path)
第二种,利用ajax或是现在浏览器的对象实现的图片预览
HTML: <div class="pics"> <div style="margin-left: 5px;position: relative"> {{ obj.avatar }} <input type="file" id="imgSelect"> <img id="previewImg" src="/static/images/default.jpg" alt="点击上传图片" title="点击上传图片"> </div> </div> JS <script> $(function () { bindAvatar() }); function bindAvatar() { if(window.URL.createObjectURL){ bindAvatar2(); } else if(window.FileReader){ bindAvatar3() }else{ bindAvatar1(); } } //ajax #需要上传到服务器 function bindAvatar1() { document.getElementById("imgSelect").onchange=function () { var formData = new FormData(); formData.append("files",$("#imgSelect")[0].files[0]); $.ajax({ url: "/upload_images/", type:"POST", data:formData, contentType:false, processData:false, dataType:"JSON", success:function (arg) { $("#previewImg").attr("src",arg.url) } }) } } //以下两种方法,否是利用现在浏览器的对象,直接从本机的内存中获取! //兼容性不高 function bindAvatar2() { document.getElementById("imgSelect").onchange=function () { var obj = this.files[0]; //获取当前文件对象 var v = window.URL.createObjectURL(obj);//把当前文件对象传入URL方法,获取当前文件的路径 document.getElementById("previewImg").src = v; document.getElementById("previewImg").onload=function () { window.URL.revokeObjectURL(v); //图片加载完成之后,释放 } } } //兼容性不高 function bindAvatar3() { document.getElementById("imgSelect").onchange=function () { var obj = this.files[0]; var reader = new FileReader(); //创建一个FileReader对象 reader.onload = function () { console.log(this.result); document.getElementById("previewImg").src=this.result; };//有内容对象就会加载,执行函数; this.result 指获取的文件对象(具体信息) reader.readAsDataURL(obj);//读取对象,在浏览器上显示 } } </script> CSS: 位置在页面的左上角 div.pics{ width: 145px; height: 150px; position: absolute; top:15%; right: 7%; border-left: 1px dotted darkgray; overflow: hidden; } div.pics img{ width: 135px; height: 150px; border-radius: 12px; opacity: 1; } div.pics #imgSelect{ position: absolute; top:0; left: 0; opacity: 0; border-radius: 12px; width: 135px; height: 150px; } views函数 def upload_images(request): file_obj = request.FILES.get("files") file_path = os.path.join("static/images",file_obj.name) with open(file_path,"wb") as f: for chunk in file_obj.chunks(): f.write(chunk) dic = { "error":0, "url":'/'+file_path, "message":" 错了...." } return HttpResponse(json.dumps(dic)) urls url(r'^upload_images/', views.upload_images,name="imag"),