视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
H5读取文件并上传到服务器的方法
2020-11-27 15:05:46 责编:小采
文档

这次给大家带来H5读取文件并上传到服务器的方法,H5读取文件并上传到服务器的方法的注意事项有哪些,下面就是实战案例,一起来看一下。

说明:使用Ajax方式上传,文件不能过大,最好小于三四百兆,因为过多的连续Ajax请求会使后台崩溃,获取InputStream中数据会为空,尤其在Google浏览器测试过程中。

1.简单分段读取文件为Blob,ajax上传到服务器

<p class="container">
 <p class="panel panel-default">
 <p class="panel-heading">分段读取文件:</p>
 <p class="panel-body">
 <input type="file" id="file" />
 <blockquote style="word-break:break-all;"></blockquote>
 </p>
 </p>
</p>

JS:

/*
* 分段读取文件为blob ,并使用ajax上传到服务器
* 分段上传exe文件会抛出异常
*/
var fileBox = document.getElementById('file');
file.onchange = function () {
 //获取文件对象
 var file = this.files[0];
 var reader = new FileReader();
 var step = 1024 * 1024;
 var total = file.size;
 var cuLoaded = 0;
 console.info("文件大小:" + file.size);
 var startTime = new Date();
 //读取一段成功
 reader.onload = function (e) {
 //处理读取的结果
 var loaded = e.loaded;
 //将分段数据上传到服务器
 uploadFile(reader.result, cuLoaded, function () {
 console.info('loaded:' + cuLoaded + 'current:' + loaded);
 //如果没有读完,继续
 cuLoaded += loaded;
 if (cuLoaded < total) {
 readBlob(cuLoaded);
 } else {
 console.log('总共用时:' + (new Date().getTime() - startTime.getTime()) / 1000);
 cuLoaded = total;
 }
 });
 }
 //指定开始位置,分块读取文件
 function readBlob(start) {
 //指定开始位置和结束位置读取文件
 //console.info('start:' + start);
 var blob = file.slice(start, start + step);
 reader.readAsArrayBuffer(blob);
 }
 //开始读取
 readBlob(0);
 //关键代码上传到服务器
 function uploadFile(result, startIndex, onSuccess) {
 var blob = new Blob([result]);
 //提交到服务器
 var fd = new FormData();
 fd.append('file', blob);
 fd.append('filename', file.name);
 fd.append('loaded', startIndex);
 var xhr = new XMLHttpRequest();
 xhr.open('post', '../ashx/upload2.ashx', true);
 xhr.onreadystatechange = function () {
 if (xhr.readyState == 4 && xhr.status == 200) {
 // var data = eval('(' + xhr.responseText + ')');
 console.info(xhr.responseText);
 if (onSuccess)
 onSuccess();
 }
 }
 //开始发送
 xhr.send(fd);
 }
}

后台代码:

/// <summary>
/// upload2 的摘要说明
/// </summary>
public class upload2 : IHttpHandler
{
 LogHelper.LogHelper _log = new LogHelper.LogHelper();
 int totalCount = 0;
 public void ProcessRequest(HttpContext context)
 {
 HttpContext _Context = context;
 //接收文件
 HttpRequest req = _Context.Request;
 if (req.Files.Count <= 0)
 {
 WriteStr("获取服务器上传文件失败");
 return;
 }
 HttpPostedFile _file = req.Files[0];
 //获取参数
 // string ext = req.Form["extention"];
 string filename = req.Form["filename"];
 //如果是int 类型当文件大的时候会出问题 最大也就是 1.9999999990686774G
 int loaded = Convert.ToInt32(req.Form["loaded"]);
 totalCount += loaded;
 string newname = @"F:\JavaScript_Solution\H5Solition\H5Solition\Content\TempFile\";
 newname += filename;
 //接收二级制数据并保存
 Stream stream = _file.InputStream;
 if (stream.Length <= 0)
 throw new Exception("接收的数据不能为空");
 byte[] dataOne = new byte[stream.Length];
 stream.Read(dataOne, 0, dataOne.Length);
 FileStream fs = new FileStream(newname, FileMode.Append, FileAccess.Write, FileShare.Read, 1024);
 try
 {
 fs.Write(dataOne, 0, dataOne.Length);
 }
 finally
 {
 fs.Close();
 stream.Close();
 }
 _log.WriteLine((totalCount + dataOne.Length).ToString());
 WriteStr("分段数据保存成功");
 }
 private void WriteStr(string str)
 {
 HttpContext.Current.Response.Write(str); 
 }
 public bool IsReusable
 {
 get
 {
 return true;
 }
 }

2.分段读取文件为blob ,并使用ajax上传到服务器,追加中止、继续功能操作

<p class="container">
 <p class="panel panel-default">
 <p class="panel-heading">分段读取文件:</p>
 <p class="panel-body">
 <input type="file" id="file" />
 <br />
 <input type="button" value="中止" onclick="stop();" /> 
 <input type="button" value="继续" onclick="containue();" />
 <br />
 <progress id="progressOne" max="100" value="0" style="width:400px;"></progress>
 <blockquote id="Status" style="word-break:break-all;"></blockquote>
 </p>
 </p>
</p>

JS:

/*
* 分段读取文件为blob ,并使用ajax上传到服务器
* 使用Ajax方式提交上传数据文件大小应该有限值,最好500MB以内
* 原因短时间过多的ajax请求,Asp.Net后台会崩溃获取上传的分块数据为空
* 取代方式,长连接或WebSocket
*/
var fileBox = document.getElementById('file');
var reader = null; //读取操作对象
var step = 1024 * 1024 * 3.5; //每次读取文件大小
var cuLoaded = 0; //当前已经读取总数
var file = null; //当前读取的文件对象
var enableRead = true;//标识是否可以读取文件
fileBox.onchange = function () {
 //获取文件对象
 file = this.files[0];
 var total = file.size;
 console.info("文件大小:" + file.size);
 var startTime = new Date();
 reader = new FileReader();
 //读取一段成功
 reader.onload = function (e) {
 //处理读取的结果
 var result = reader.result;
 var loaded = e.loaded;
 if (enableRead == false)
 return false;
 //将分段数据上传到服务器
 uploadFile(result, cuLoaded, function () {
 console.info('loaded:' + cuLoaded + '----current:' + loaded);
 //如果没有读完,继续
 cuLoaded += loaded;
 if (cuLoaded < total) {
 readBlob(cuLoaded);
 } else {
 console.log('总共用时:' + (new Date().getTime() - startTime.getTime()) / 1000);
 cuLoaded = total;
 }
 //显示结果进度
 var percent = (cuLoaded / total) * 100;
 document.getElementById('Status').innerText = percent;
 document.getElementById('progressOne').value = percent;
 });
 }
 //开始读取
 readBlob(0);
 //关键代码上传到服务器
 function uploadFile(result, startIndex, onSuccess) {
 var blob = new Blob([result]);
 //提交到服务器
 var fd = new FormData();
 fd.append('file', blob);
 fd.append('filename', file.name);
 fd.append('loaded', startIndex);
 var xhr = new XMLHttpRequest();
 xhr.open('post', '../ashx/upload2.ashx', true);
 xhr.onreadystatechange = function () {
 if (xhr.readyState == 4 && xhr.status == 200) {
 if (onSuccess)
 onSuccess();
 } else if (xhr.status == 500) {
 //console.info('请求出错,' + xhr.responseText);
 setTimeout(function () {
 containue();
 }, 1000);
 }
 }
 //开始发送
 xhr.send(fd);
 }
}
//指定开始位置,分块读取文件
function readBlob(start) {
 //指定开始位置和结束位置读取文件
 var blob = file.slice(start, start + step);
 reader.readAsArrayBuffer(blob);
}
//中止
function stop() {
 //中止读取操作
 console.info('中止,cuLoaded:' + cuLoaded);
 enableRead = false;
 reader.abort();
}
//继续
function containue() {
 console.info('继续,cuLoaded:' + cuLoaded);
 enableRead = true;
 readBlob(cuLoaded);
}

后台代码同上

3.分段读取文件为二进制数组 ,并使用ajax上传到服务器

使用二进制数组传递的方式,效率特别低,最终文件还与原始大小有些偏差

HTML内容同上

JS:

/*
 * 分段读取文件为二进制数组 ,并使用ajax上传到服务器
 * 使用二进制数组传递的方式,效率特别低,最终文件还与原始大小有些偏差
 */
var fileBox = document.getElementById('file');
var reader = new FileReader(); //读取操作对象
var step = 1024 * 1024; //每次读取文件大小
var cuLoaded = 0; //当前已经读取总数
var file = null; //当前读取的文件对象
var enableRead = true;//标识是否可以读取文件
fileBox.onchange = function () {
 //获取文件对象
 if (file == null) //如果赋值多次会有丢失数据的可能
 file = this.files[0];
 var total = file.size;
 console.info("文件大小:" + file.size);
 var startTime = new Date();
 //读取一段成功
 reader.onload = function (e) {
 //处理读取的结果
 var result = reader.result;
 var loaded = e.loaded;
 if (enableRead == false)
 return false;
 //将分段数据上传到服务器
 uploadFile(result, cuLoaded, function () {
 console.info('loaded:' + cuLoaded + '----current:' + loaded);
 //如果没有读完,继续
 cuLoaded += loaded;
 if (cuLoaded < total) {
 readBlob(cuLoaded);
 } else {
 console.log('总共用时:' + (new Date().getTime() - startTime.getTime()) / 1000);
 cuLoaded = total;
 }
 //显示结果进度
 var percent = (cuLoaded / total) * 100;
 document.getElementById('Status').innerText = percent;
 document.getElementById('progressOne').value = percent;
 });
 }
 //开始读取
 readBlob(0);
 //关键代码上传到服务器
 function uploadFile(result, startIndex, onSuccess) {
 var array = new Int8Array(result);
 console.info(array.byteLength);
 //提交到服务器
 var fd = new FormData();
 fd.append('file', array);
 fd.append('filename', file.name);
 fd.append('loaded', startIndex);
 var xhr = new XMLHttpRequest();
 xhr.open('post', '../ashx/upload3.ashx', true);
 xhr.onreadystatechange = function () {
 if (xhr.readyState == 4 && xhr.status == 200) {
 // console.info(xhr.responseText);
 if (onSuccess)
 onSuccess();
 } else if (xhr.status == 500) {
 console.info('服务器出错');
 reader.abort();
 }
 }
 //开始发送
 xhr.send(fd);
 }
}
//指定开始位置,分块读取文件
function readBlob(start) {
 //指定开始位置和结束位置读取文件
 var blob = file.slice(start, start + step);
 reader.readAsArrayBuffer(blob);
}
//中止
function stop() {
 //中止读取操作
 console.info('中止,cuLoaded:' + cuLoaded);
 enableRead = false;
 reader.abort();
}
//继续
function containue() {
 console.info('继续,cuLoaded:' + cuLoaded);
 enableRead = true;
 readBlob(cuLoaded);
}

后台代码:

/// <summary>
/// upload3 的摘要说明
/// </summary>
public class upload3 : IHttpHandler
{
 LogHelper.LogHelper _log = new LogHelper.LogHelper();
 int totalCount = 0;
 public void ProcessRequest(HttpContext context)
 {
 HttpContext _Context = context;
 //接收文件
 HttpRequest req = _Context.Request;
 string data = req.Form["file"];
 //转换方式一
 //int[] intData = data.Split(',').Select(q => Convert.ToInt32(q)).ToArray();
 //byte[] dataArray = intData.ToList().ConvertAll(x=>(byte)x).ToArray();
 //转换方式二
 byte[] dataArray = data.Split(',').Select(q => int.Parse(q)).Select(q => (byte)q).ToArray();
 //获取参数
 string filename = req.Form["filename"];
 //如果是int 类型当文件大的时候会出问题 最大也就是 1.9999999990686774G
 int loaded = Convert.ToInt32(req.Form["loaded"]);
 totalCount += loaded;
 string newname = @"F:\JavaScript_Solution\H5Solition\H5Solition\Content\TempFile\";
 newname += filename;
 try
 {
 // 接收二级制数据并保存
 byte[] dataOne = dataArray;
 FileStream fs = new FileStream(newname, FileMode.Append, FileAccess.Write, FileShare.Read, 1024);
 try
 {
 fs.Write(dataOne, 0, dataOne.Length);
 }
 finally
 {
 fs.Close();
 }
 _log.WriteLine((totalCount + dataOne.Length).ToString());
 WriteStr("分段数据保存成功");
 }
 catch (Exception ex)
 {
 throw ex;
 }
 }
 private void WriteStr(string str)
 {
 HttpContext.Current.Response.Write(str);
 }
 public bool IsReusable
 {
 get
 {
 return false;
 }
 }
}

相信看了本文案例你已经掌握了方法,更多精彩请关注Gxl网其它相关文章!

推荐阅读:

html5怎么实现图片转圈的动画效果

H5实现桌面通知

下载本文
显示全文
专题