js的FileReader實現圖片文件上傳、預覽
FileReader對象的readAsDataURL方法可以將讀取到的文件編碼成Data URL。
Data URL是一項特殊的技術,可以將資料(例如圖片)內嵌在網頁之中,不用放到外部文件。
使用Data URL的好處是,您不需要額外再發出一個HTTP 請求到服務器端取得額外的資料;
而缺點便是,網頁的大小可能會變大。它適合應用在內嵌小圖片,不建議將大圖像文件編碼成Data URL來使用。您的圖像文件不能夠超過瀏覽器限定的大小,否則無法讀取圖像文件。
1.參考以下使用readAsDataURL讀取圖像文件范例:
Sign.Uploadxy = function () { var file = files.files[0]; if (!!file) { var qybsm = $("#qybsm").val(); var fr = new FileReader(); fr.onloadend = function () { var res = fr.result;//獲取文件內容 var param = "{ 'qybsm':'" + qybsm + "','file':'" + res + "','filename':'" + file.name + "'}"; $.ajax({ type: "post", async: false, contentType: "application/json; charset=utf-8", data: param, url: XXX + "Service/XXXManageService.asmx/XXX", dataType: 'json', success: function (msg) { var data= JSON.parse(msg.d); if (data.code == "1") { alert('成功!'); } else { alert('失敗!'+data.msg); } }, error: function (e) { alert('失敗!請重試'); } }); } fr.onerror = function () { alert('失敗!請重試'); } fr.readAsDataURL(file); //base64讀取 事件必須聲明在讀取之前否則不會觸發 } }
通過FileReader對象fr讀取文件(fr.readAsDataURL(file))內容,通過fr.result就可以把文件內容傳遞到后台代碼處理。
2.后台代碼把文件內容轉換成byte數組( Convert.FromBase64String(file.Substring(file.IndexOf(",") + 1))),這樣就可以把文件內容存儲到數據庫對應的大字段里面,以文件方式存儲。如下代碼所示:
public string XXX(string qybsm, string file, string fileName) { Dictionary<string, string> map = new Dictionary<string, string>(); if (string.IsNullOrEmpty(file)) { map.Add("code", "0"); map.Add("msg", "附件不能為空,請上傳"); return JavaScriptConvert.SerializeObject(map); } CommonBus bus = new CommonBus(); string qyzx ="XXX"; int f_site_id =0; byte[] data = Convert.FromBase64String(file.Substring(file.IndexOf(",") + 1));//去掉多余的base64字符 try { BGDataService.BeginTransaction(); string sql = @"insert into xx s (sign_id, qybsm, qyzx, xysmj, f_site_id, xysmjmc) values (sys_guid(), @0, @1, @2, @3, @4)"; BGDataService.Execute(sql, qybsm, qyzx, data, f_site_id,Path.GetFileNameWithoutExtension(fileName)); BGDataService.CompleteTransaction(); map.Add("code", "1"); map.Add("msg", ""); return JavaScriptConvert.SerializeObject(map); } catch (Exception e) { BGDataService.AbortTransaction(); map.Add("code", "0"); map.Add("msg", e.Message); return JavaScriptConvert.SerializeObject(map); } }
3.文件保存數據庫成功后,可以通過讀取文件流方式來顯示文件,readAsDataURL方法會使用base-64進行編碼,編碼的資料由data字串開始,后面跟隨的是MIME type,然后再加上base64字串,逗號之后就是編碼過的圖像文件的內容。
使用Img顯示圖像文件 。若想要將讀取出來的圖像文件,直接顯示在網頁上,您可以透過JavaScript建立一個<img>標簽,再設定src屬性為Data URL,再將<img>標簽加入DOM之中如下代碼所示:
Sign.look = function (type) { var sign_id = $("#sign_id").val(); var img; var send = "{'sign_id':'" + sign_id + "'}"; img = Global.GetServerDataJson("XXManage.XXManageData", "Qryxx", send, "Business", null, false); var html = '<div style="text-align: center;overflow:auto;width:100%;height:100%"><img src="' + img + '"/></div>'; top.Dialog.open({ Title: "查看附件", InnerHtml: html, Width: 1000, Height: 670 }); }
通過后台方法把字節數組讀取返回js顯示,后台處理方法如下所示:
public string QryZzjgdmfj(string qybsm) { try { string StrSql = string.Format("select x.FILE_YYZZ tempimg,'' img from xx x where x.bsm=@0"); DataTable page = BGDataService.Query4DataTable(StrSql, qybsm); DataTable qyfjDt = page; for (int i = 0; i < qyfjDt.Rows.Count; i++) { byte[] cont = null; if (qyfjDt.Rows[i]["tempimg"].ToString().Length > 0) cont = (byte[])qyfjDt.Rows[i]["tempimg"]; if (cont != null && cont.Length > 0) { qyfjDt.Rows[i]["img"] = "data:image/jpeg;base64," + Convert.ToBase64String(cont); } } qyfjDt.Columns.Remove("tempimg"); string strJson = qyfjDt.Rows[0]["img"].ToString(); return strJson; } catch (Exception ex) { throw ex; } }
通過以上步驟,即可以完成文件的上傳和預覽。
讀取部分文件
有時想要讀取的文件太大,想要分段進行讀取;或者只想要讀取文件部分的內容,這時您可以將文件切割,根據瀏覽器的不同,可以使用以下方法:
webkitSlice:適用於支持Webkit引擎的瀏覽器,如Chrome。
mozSlice:適用於Firefox。
這兩個方法要傳入開始的位元組索引,以及結尾的位元組索引,索引以0開始。以下程式范例以FileReader對象的readAsBinaryString方法來讀取文件,只讀取文件的第三個位元組讀取到第六個位元組:
請注意:
不同的瀏覽器對於HTML 5的支持程度不同,上述程式碼可在chrome正常執行,不見得可以在其它瀏覽器中正確的執行。