如果那寫錯了,或者那寫的不對路子請幫忙說出來,我好改正,嘿嘿進步都是一點點的喲!~
正文之前
搞不清楚是上傳控件的腦殘還是我下午腦袋缺氧。這種情況搞不懂是不是常見的形態之一了。
正文之前結束
今天陽光明媚(摔!風很大!),抱着愉悅的心情來等待測試的bug。我個人很有信心木有bug(摔!MB倆模塊測試出6個BUG)。沒想到第一個BUG出來了。而這個BUG也是這個文章的略點,就不說了,當第3個BUG出來的時候我才知道,今天下午是災難性的。
問題出現在上傳控件上,為了跟后端友好的交互果斷拖了個上傳控件。客戶需求是當點擊上傳控件的瀏覽的時候
就是下圖
要顯示這個圖片,當然這個圖片是不上傳的話是極好的(摔!)
好吧,抱着客戶是上帝的想法我果斷的寫出了如下的JS代碼
$(function () { $("#fileupImg").change(function () { var turl = $("#XXOO").val().replace(':\\', '^').split('^')[1]; var location = "file:///" + turl; var type = location.substr(location.lastIndexOf(".")).toLowerCase(); var img = new Image(); if (type == ".jpg" || type == ".gif" || type == ".jpeg" || type == ".bmp") { img.src = location; img.onload = function () { if (img.width < 1355 || img.width >= 1365) { alert("上傳圖片的寬度要在1355到1365像素之間"); return; } if (img.height < 1015 || img.height > 1025) { alert("上傳圖片的高度要在1015到1025像素之間"); return; } $("#yiku").attr("src", location); $("#yiku").show(); } } else { alert("圖片格式不對!"); } }) });
這段代碼在編寫階段的時候是木有問題的(TMD,當時老子要測試下盤符可否顯示就好了)
在桌面上傳圖片的時候什么問題都沒有,當然也可能出現問題,這個一會在說。
測試人員告訴我,上傳的圖片不顯示。我就好奇為什么呢,找她要一下測試圖片,自己測試下發現,連桌面的都無法顯示,並且看到的源碼並不是跟我設想的一樣。這個時候我就在考慮原因是什么,首先進入腦簾的就是,權限問題。
瀏覽器是否有權限讀寫用戶的硬盤信息,換種說法JS是否有權限操作硬盤信息?我想應該是沒有,但是為什么本地的源碼就可以獲取到桌面的圖片呢,我想大概是因為我在本地測試,本地預覽有關系,希望知道的大牛幫我解答下這個問題。
時間一分一秒的過去了,突然想到,這個方法如果不行怎么辦。有的觀眾會說了用第三方啊。親,第三方是不讓用的,並且我還需要知道他上傳圖片的尺寸,在上面的代碼你們也看到了我需要判斷尺寸來決定是否上傳。這時候,我想起了親愛的谷歌。在谷歌上搜索無數個關鍵字,終於找到一個關鍵字,濾鏡。
JS還有濾鏡?這個是我頭一次聽說,難道美圖秀秀是用JS寫的?
谷歌的辦法無非就是通過濾鏡來把圖片加載到,我竊喜,終於找到解決辦法了!上代碼!~
imgDiv.style.width="必填"; imgDiv.height="必填"; imgDiv.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod = scale)"; imgDiv.get(0).filters.item("DXImageTransform.Microsoft.AlphaImageLoader").sizingMethod = "image";
這個是關鍵代碼。經過測試,這個代碼在瀏覽器安全級別很低的情況下可用,如果您的客戶瀏覽器安全級別很低,可以使用這段話。
網上是 sizingmethod=scale; 這么寫我的沒有分號,如果有分號那么他容器就會失效,搞不懂網上為什么都這么寫。容器失效的后果就是圖片出來之后是原尺寸。
當然,我說了這個是在瀏覽器安全級別很低的情況下沒問題,而默認的瀏覽器安全級別都是 中或者是中-高。
這樣就涉及到一個屬性
這個屬性,他會讓你的上傳控件路徑變成 X:\fakepath\文件名,你們看到了他把真實路徑給掩蓋了(瀏覽器掩蓋了事實的真相!!!)。查到的相關資料大意是因為瀏覽器需要安全,從IE7開始路徑就給安全化了。
那么怎么辦呢。我們可以在獲取 物理路徑的時候寫上
下面這段話
var file = document.getElementById('XXOO'); file.select(); file.blur();
var a= document.selection.createRange().text;
這樣就能獲取到真實的路徑了,然后就可以做你想做的事情了,這樣上面的瀏覽器安全級別低的那段代碼也就可以用了(我沒測試,但是應該沒問題)。
接下來我要面對的是另一個問題,圖片我獲取不到他的寬度和高度。當然有的客官說了,你都獲取到真實地址了怎么能獲取不到寬度高度呢,我沒測試,但是應該不能,在IE7之后的安全策略里面,現在是不讓獲取本地文件屬性的。
到這個時候已經是臨近下班的點了,我還想下班回家玩XBOX呢。沒辦法只能把情況如實的反應一下,后來要求我限期整改,選擇圖片的時候可以上傳但是木有上傳按鈕,頁面不能刷新,當然這都是簡單的解決(啊?你不會?我沒辦法了動腦想一下就能解決)。
最終解決方案是上傳一張圖片。
有的人也問了,為什么當初設計的時候不讓上傳呢?因為我們這個上傳還涉及到很多東西,綜合下來如果上傳一次的話性能下降很多,要做大量的IO讀寫。而現的上傳是上傳到臨時的文件夾里面,當確定這條數據的時候刪除臨時文件夾里面的這一個文件,而非多次IO讀寫。性能提高一些。
當搞定這些問題的時候已經是快9點了。后面幾個BUG都是哭笑不得的疏忽,這樣的疏忽,讓我老臉通紅。。
下午學到了這些知識,我覺得很不錯了,至少知道了 IE瀏覽器的安全策略和幾個上傳的方法。
今天是多么美好的一天那。
以上代碼是IE 7 8 9未測試 其他瀏覽器。
PS:還有一種是HTML5的方式也很有意思,這個是群里的朋友幫我提供的。
1 <style> 2 .thumb { 3 height: 75px; 4 border: 1px solid #000; 5 margin: 10px 5px 0 0; 6 } 7 </style> 8 9 <input type="file" id="files" name="files[]" multiple /> 10 <output id="list"></output> 11 12 <script> 13 function handleFileSelect(evt) { 14 var files = evt.target.files; // FileList object 15 16 // Loop through the FileList and render image files as thumbnails. 17 for (var i = 0, f; f = files[i]; i++) { 18 19 // Only process image files. 20 if (!f.type.match('image.*')) { 21 continue; 22 } 23 24 var reader = new FileReader(); 25 26 // Closure to capture the file information. 27 reader.onload = (function(theFile) { 28 return function(e) { 29 // Render thumbnail. 30 var span = document.createElement('span'); 31 span.innerHTML = ['<img class="thumb" src="', e.target.result, 32 '" title="', escape(theFile.name), '"/>'].join(''); 33 document.getElementById('list').insertBefore(span, null); 34 }; 35 })(f); 36 37 // Read in the image file as a data URL. 38 reader.readAsDataURL(f); 39 } 40 } 41 42 document.getElementById('files').addEventListener('change', handleFileSelect, false); 43 </script>