用火狐、谷歌調試圖片的預覽和上傳可謂是怎麼弄怎麼行,只要你說出需求,但是到了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瀏覽器。