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;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正常执行,不见得可以在其它浏览器中正确的执行。