用火狐、谷歌调试图片的预览和上传可谓是怎么弄怎么行,只要你说出需求,但是到了IE下,就出现了各类各样的问题,可是无论你遇到什么样的问题,总会有解决的办法,尽管有时候办法可能会笨拙 、麻烦、费时、费力、很差看。html
选择图片固然很简单,用一个input file标签,点击就会弹出文件选择框。固然也不那么简单,每每咱们都嫌弃自带按钮很差看或是与你的操做逻辑不匹配,这就须要事件转移或者是按钮覆盖。哎,从何提及呢?
java
火狐、谷歌……数据库
页面中加入文件选择器标签,opacity:0使标签为透明,也能够display:none浏览器
<input type="file" id="choose-img" onchange="setImagePreview();" style="opacity:0">
将选择按钮的点击事件转移安全
button.onclick = function(){$("#choose-img").click()};
这样按钮的样式就能够彻底按你的喜爱来设置了,也能够是连接、div、随便服务器
文件选择器的onchange事件
app
function setImagePreview(event) { var imagechoose=document.getElementById("choose-img"); /* var fileName = imagechoose.value; if (!fileName.match(/.jpg|.jpeg|.gif|.png|.bmp/i)) { alert('您上传的图片格式不正确,请从新选择!'); return false; } */ var imgObjPreview=document.getElementById("preview-img"); //预览图片的<img> if(imagechoose.files && imagechoose.files[0]){ var formData = new FormData(); // >=IE10 Partial support formData.append("id",selectedId); formData.append("file",imagechoose.files[0]); //火狐下,直接设img属性 //imgObjPreview.src = imagechoose.files[0].getAsDataURL(); //火狐7以上版本不能用上面的getAsDataURL()方式获取,须要一下方式 imgObjPreview.src = window.URL.createObjectURL(imagechoose.files[0]); } }
这样在页面上就能够看到用户选择的图片了,由于调用的是onchange事件,因此若是两次选择同一图片是不会调用这个方法的,由于没有change。函数
文件上传使用了简单方便的XMLHttpRequestpost
var xhrup = new XMLHttpRequest(); xhrup.open("POST", "后台接收路径"); xhrup.send(formData); //上一个方法中保存的FormData,其余参数也能够一块儿传
也能够添加回调函数,XMLHttpRequest上传文件和请求文件都很好用ui
后台接收
@RequestMapping("/uploadImage") public @ResponseBody void uploadImage(MultipartHttpServletRequest request,HttpServletResponse response)throws Exception { try{ Map getMap = request.getFileMap(); String id = request.getParameter("id"); MultipartFile mfile = (MultipartFile) getMap.get("file"); InputStream file = mfile.getInputStream(); byte[] fileByte = FileCopyUtils.copyToByteArray(file); Map<String, Object> setMap = new HashMap<String, Object>(); setMap.put("id",id); setMap.put("file", fileByte); bulletinService.uploadImage(setMap); //保存到数据库 operatelogService.addOperateLogInfo(request, "上传成功:成功上传图片"); }catch (Exception e) { e.printStackTrace(); operatelogService.addOperateLogError(request, "上传失败:服务器异常"); } }
IE9
下面就要一项一项地说说以上方法都是如何不行的了。
若是你给input file设成了display:none,那它必定没法给你弹出文件选择对话框了,设成opacity:0才免为其难能够了,若是你设了opacity:0仍是能看见,不妨重启机试试。
文件提交,不支持FormData格式,也获取不到文件的byte数据,因为它的安全机制,文件路径和文件数据对你来讲都是保密的,只能用form表单提交。提交后form的返回是一个页面,若是不想刷新页面,怎么办嘞,隐藏iframe。
事件转移,是能够的,不过,当你要提交表单的时候,它会检查表单要提交的内容,这一检查就检查出问题了,它认定你的input file不是用户选择赋值,而是js人为修改了它的值,因此在提交表单以前要清空你人为修改的东西,也就是说,你选了,它也让你选了,你要提交,它却把你选的东西清了再提交,后台什么也收不到。
这样事件转移就不能用了,可使用按钮覆盖的方法,很麻烦,很差调。把input file设成opacity:0,在其上覆盖你的按钮或其余,当用户点击你的按钮时,实际是点击到了input file的浏览按钮。固然,也能够直接用原生态的,就简单了。
再说说这个预览,刚开始我是用的获取文件的真实全路径,而后用滤镜显示。这个是能够的,但后来因为我不清楚的缘由,文件全路径获取不到了,简直坑死。
因此我用了将文件上传到服务器,再向服务器请求这个文件来显示。麻烦,稳妥。
IE滤镜预览图片
imagechoose.select(); imagechoose.blur(); // imgObjPreview.focus(); window.parent.document.body.focus(); // window.top.document.body.focus(); var imgSrc = document.selection.createRange().text; //这个理论上回获取到文件的全路径 // var imgSrc = $("#"+event.target.id).val(); //必须设置初始大小 imgObjPreview.style.width = ; imgObjPreview.style.height = ; //图片异常的捕捉,防止用户修改后缀来伪造图片 imgObjPreview.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=scale)"; imgObjPreview.filters.item("DXImageTransform.Microsoft.AlphaImageLoader").src = imgSrc;
form表单
<form action="后台接收路径" id="" target="隐藏iframe的name" method="post" enctype="multipart/form-data"> <input type="file" id="" onchange=""> </form>
input file的onchange事件
var uploadform = document.getElementById("包含input的表单的ID"); uploadform.submit();
后台接收
@RequestMapping("/uploadImage4ie") public ModelAndView uploadImage4ie(@RequestParam("imgFile") MultipartFile imgFile,HttpServletRequest request,HttpServletResponse response)throws Exception { ModelAndView mav = new ModelAndView(); mav.setViewName("返回页面"); try{ String imgId = request.getParameter("imgId"); byte[] imgByte = imgFile.getBytes(); String cuid = CUID.cuid(4); //文件保存路径 String imagePath = (new File(this.getClass().getClassLoader().getResource("").toURI().getPath())).getParentFile().getParentFile().getPath()+"/images/docPreview/"+imgId+cuid+".jpg"; FileImageOutputStream imageOutput = new FileImageOutputStream(new File(imagePath)); imageOutput.write(imgByte, 0, imgByte.length); imageOutput.close(); request.setAttribute("preId", imgId.substring(5)); request.setAttribute("imgSrc", "images/docPreview/"+imgId+cuid+".jpg"); operatelogService.addOperateLogInfo(request, "上传成功:成功上传图片"); }catch (Exception e) { e.printStackTrace(); operatelogService.addOperateLogError(request, "上传失败:服务器异常"); } return mav; }
隐藏iframe
<iframe name='nofreshIframe' style='display: none;'></iframe>
在返回页面中设置预览<img>的src为请求图片路径
var src = document.getElementById("imgSrc").value; var id = document.getElementById("preId").value; var imgP = parent.document.getElementById(id); imgP.src = src; parent.setImgSrc(id,src);
这样就基本完成了,IE是一项能把人累死和逼疯的工做,漫漫长路,无穷无尽,真爱生命,远离IE浏览器。