<!DOCTYPE HTML> <html> <head> <meta content="text/html" charset="utf-8" /> <meta name="viewport" content="initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" /> <title>upload file3 - h5讀取文件流</title> </head> <body> <input type="file" accept="image/*" id="J_upload_btn" /> <div id="J_preview_area"> </div> <script src="jquery-1.9.1.min.js"></script> <script> $('body').on('change','#J_upload_btn',function(){ var source = $(this).get(0), file = source.files[0]; var ireg = /image\/.*/i, file_type = file.type, file_name = file.name; if(!file_type.match(ireg)) { alert('不是圖片,請重新選擇'); }else{ if(window.FileReader) { var fr = new FileReader(); fr.onloadend = function(e) { var file_data; // 此處不做任何壓縮直接讀取文件流顯示為圖片(可擴展為壓縮圖片后顯示) file_data = e.target.result; $('#J_preview_area').html('<img src="'+file_data+'" />'); var url = 'upload_file2.php'; var xmlhttp; if (window.XMLHttpRequest) { //IE7+, Firefox, Chrome, Opera, Safari xmlhttp = new XMLHttpRequest; //針對某些特定版本的mozillar瀏覽器的bug進行修正 if (xmlhttp.overrideMimeType) { xmlhttp.overrideMimeType('text/xml'); }; } else if (window.ActiveXObject){ //IE6, IE5 xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); }; if(xmlhttp.upload){ //2.回調函數 xmlhttp.onreadystatechange = function(e){ if(xmlhttp.readyState == 4){ if(xmlhttp.status == 200){ var json = eval('(' + xmlhttp.responseText + ')'); console.log(json); }else{ console.log(xmlhttp.responseText); } } }; //3.設置連接信息 xmlhttp.open("POST",url,true); //4.發送數據,開始和服務器進行交互 var formdata = new FormData(); // file_data.split(",")[1],此處文件流為base64后的結果,需要將結果中的逗號前的信息去除(逗號前是給image標簽顯示用的) formdata.append("file_content", file_data.split(",")[1]); formdata.append("file_name", file_name); formdata.append("file_type", file_type); xmlhttp.send(formdata); } }; fr.readAsDataURL(file); } } }); </script> </body> </html>
使用HTML5讀取圖片顯示縮略圖,並使用文件流方式上傳有以下幾個注意點:
1、此方法和之前介紹的文件指針方式略有不同,是直接把文件流讀取出來進行上傳
2、此方法需支持HTML5的FileReader(即ie10+)
3、選擇圖片時,首先需要在input type="file” 加上accept的類型,其次也需要js進行正則校驗文件的type(由於accept只是在文件選擇器打開時篩選出符合條件的文件供用戶選擇,用戶任然可以切換到所有文件,所以需要加上js的正則過濾,以確保文件類型正確)
4、由於FileReader讀取文件流是一個異步的過程,圖片預覽必須寫在FileReader的onloadend函數中,等文件流讀取完畢后才能獲取到base64之后的圖片流,由於是直接把文件流上傳,所以立即上傳的操作也必須是寫在FileReader的onloadend函數中,等文件流讀取完畢后才能將獲取到的文件流上傳(不是立即上傳,而是點擊按鈕上傳的,也需要有標志位控制告訴是否文件流已經讀取完畢)
5、上傳的文件流需要切分,讀取為base64的圖片流有(data:image/png;base64,...)這樣的頭,需要把逗號之前的切掉才是真實的base64的文件流
6、這個方法是用http模擬ajax的方法異步上傳文件,所以頁面不會跳轉,但是值得注意的是傳統jQuery中的ajax是無法上傳文件的