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方法来读取文件,只读取文件的第三个位元组读取到第六个位元组:
<!DOCTYPE html>
<html xmlns ="http://www.w3.org/1999/xhtml" >
<head>
<title> </title>
<script type = "text/javascript" >
function ProcessFile( e ) {
var file = document.getElementById( 'file' ).files[0];
if ( file ) {
var reader = new FileReader ();
reader.onload = function ( event ) {
var txt = event.target.result;
document.getElementById( "result" ).innerHTML = txt;
};
}
if ( file.webkitSlice ) {
var blob = file.webkitSlice( 2, 4 );
} else if ( file.mozSlice ) {
var blob = file.mozSlice( 2, 4 );
}
reader.readAsBinaryString( blob );
}
function contentLoaded() {
document.getElementById( 'file' ).addEventListener( 'change' ,
ProcessFile , false );
}
window.addEventListener( "DOMContentLoaded", contentLoaded , false );
</script>
</head>
<body>
<input type = "file" id = "file" name = "file" />
<div id = "result" > </div>
</body>
</html>
请注意:
不同的浏览器对于HTML 5的支持程度不同,上述程式码可在chrome正常执行,不见得可以在其它浏览器中正确的执行。