发布时间:2017-03-23责任编辑:朱明 浏览:2328
一般在做文件上传的时候,都是通过客户端把要上传的文件上传到服务器,此时上传的文件都在服务器内存,如果上传的是视频等大文件,那么服务器内存就很紧张,而且一般我们都是用flash或者html5做异步上传,如果文件比较大的话,即便是客户端显示文件已经上传了100%,还是会有一个比较长时间的等待,而且当前页面对服务器的请求也会被阻塞。
在侣行项目中上传视频文件为解决这种问题,采用百度开源的上传组件webuploader,官方介绍webuploader支持大文件分片断点上传。具体webuploader的使用方法见官网http://fex.baidu.com/webuploader/。
具体使用方法,考参考如下:
1. 引如外部资源 css,js文件(资源从官网下载即可)
<link href="/areas/common/WebUploader/webuploader.css" rel="stylesheet">
<script type="text/javascript" charset="utf-8" src="/areas/common/WebUploader/webuploader.min.js"></script>
2. .写容器DOM用来放置webuploader的dom
<span style="font-size:14px;"><div id="uploader-demo">
<!--用来存放item-->
<div id="thelist" class="uploader-list"></div>
<div>
<div id="filePicker">选择图片</div>
<button id="ctlBtn" class="btn btn-default">开始上传</button>
</div>
</div>
</span>
3. 初始化webuploader组件,设置上传等事件监听。
var guid = WebUploader.Base.guid();//一个GUID
var dt= new Date();
var dateNow = dt.getFullYear()+"-"+(dt.getMonth() + 1) + "-"+ dt.getDate();
this.uploader = new WebUploader.Uploader({
// 选完文件后,是否自动上传。
auto: false,
// swf文件路径
swf: '/areas/common/WebUploader/Uploader.swf',
// 文件接收服务端。
server: '/common/WebUploader/Upload',
// 选择文件的按钮。可选。
// 内部根据当前运行是创建,可能是input元素,也可能是flash.
pick: {
id: this.filepicker.nativeElement,
multiple: false
},
accept: {
mimeTypes: 'video/*,audio/*'// 选择文件类型限定
},
chunked: true,//开始分片上传
chunkSize: 2048000,//每一片的大小2M
formData: {
date:dateNow,
guid: guid //自定义参数
},
// 不压缩image, 默认如果是jpeg,文件上传前会压缩一把再上传!
resize: false
});
// 当有文件被添加进队列的时候
this.uploader.on('fileQueued', file => {
this.file.id = file.id;
this.file.name = file.name;
this.file.state = "等待上传";
});
// 文件上传过程中创建进度条实时显示。
this.uploader.on('uploadProgress', (file, percentage) => {
this.file.state = "上传中";
this.progressWidth = this.domSanitizer.bypassSecurityTrustStyle((percentage*100)+"%");
});
// 文件上传成功,给item添加成功class, 用样式标记上传成功。
this.uploader.on('uploadSuccess', (file, response) => {
this.file.state = "已上传";
$.post('/common/WebUploader/Merge', { guid: guid, fileName: file.name, date:dateNow}, result => {
if (result.Flag) {
this.file.state = "上传成功...";
this.videoSrcChange.next(result.Data);
}
});
});
// 文件上传失败,显示上传出错。
this.uploader.on('uploadError', file => {
this.file.state = '上传出错';
this.showFilePicker=true;
});
// 完成上传完了,成功或者失败,先删除进度条。
this.uploader.on('uploadComplete', file => {
this.file = { id: null, name: null, state: null, src: null, showprogress: false };
this.showFilePicker=true;
this.uploader.removeFile(file,true);
});
//所有文件上传完毕
this.uploader.on("uploadFinished", () => {
//提交表单
});
webuploader的分片上传是把文件分成若干份,然后向你定义的文件接收端post数据,如果上传的文件大于分片的尺寸,就会进行分片,然后会在post的数据中添加form元素chunk标示当前分片在上传分片中的顺序(从0开始)。Chunks标示总分片数。
选择一个文件后分了7个分片,所以请求7次post数据的过程。

4. 服务器端接收数据,处理上传文件。
//处理分片的文件
[HttpPost]
public JsonResult Upload()
{
CommonResult commonResult = new CommonResult();
commonResult.Flag = false;
int index = Convert.ToInt32(Request["chunk"]);//当前分块序号
var guid = Request["guid"];//前端传来的GUID号
var now = Convert.ToDateTime(Request["date"]);
var filePath = string.Format("/upload/{0}/{1}/{2}/{3}", now.Year, now.Month, now.Day, guid);//设置临时存放文件夹名称
string dir = Server.MapPath("~" + filePath); //临时保存分块的目录
if (!System.IO.Directory.Exists(dir))
&