一、简介
本文实例主要讲述了ng-cli 与JS+html5实现异步文件上传进度条显示功能

二、ng-cli版本
使用了angular-cli、NG-ZORRO中的nz-upload

 

1)http.service.ts:

 /**
 * 请求主体可以为 urlencoding、JSON、FormData 的 POST 请求
* @param _url|string 请求地址
* @param _params|ParamsType 参数对象
* @param contentType|ContentType Post请求body编码格式
* @param safeResponse|HttpResponseType 请求错误时的返回值
* @param userNotification|boolean 是否显示操作提示弹框
* @param errorSource|string 引起错误的操作来源
*/
Post(_url: string, _params: ParamsType, contentType: PostContentType, safeResponse: HttpResponseType,
   userNotification: boolean = true, errorSource: string = '', useErrMsg: boolean = false): Observable<HttpResponseType> {
   const URL = this.URLPattern.test(_url) ? _url : environment.baseURL + _url;
   const contentTypeArray = [new HttpParams({ fromObject: _params }), _params, this.toFormData(_params)];
   let messageID = '';
   const headerParam = this.getLoginInfo();
if (userNotification) {
   messageID = this.message.loading('编辑中...', { nzDuration: 0 }).messageId;
}
 return this.httpClient.post(URL, contentTypeArray[contentType], {
   headers: new HttpHeaders(headerParam),
   reportProgress: true
}).pipe(
map((response: HttpResponseType) => {
   this.message.remove(messageID);
   if (response['code'] === 200) {
   this.message.success('编辑成功');
} else {
  this.message.error(useErrMsg ? response.msg : '编辑失败');
}

return response;
}),
catchError(this.handleError(safeResponse, errorSource, messageID, '编辑'))
);
}

2)xxx.html:

<div class="upFiles">
<div class="spangrup">上传配置文件</div>
<div>
<nz-upload style="display: inline-block" nzType="drag" nzAction='{{fileUrlSite}}' [nzCustomRequest]="customReq">
<p class="ant-upload-drag-icon">
<i nz-icon nzType="upload"></i>
</p>
<p class="ant-upload-text">点击或将文件拖拽到这里上传</p>
</nz-upload>
</div>
</div>

3)xxx.ts:

/**
* 上传文件模块
*/
import { HttpClient, HttpEvent, HttpEventType, HttpRequest, HttpResponse } from '@angular/common/http';       //需引入
customReq = (item: UploadXHRArgs) => {
    const formData = new FormData();
    formData.append('file', item.file as any);
    const req = new HttpRequest('POST', item.action!, formData, {
    reportProgress: true
});
 return this.http.request(req).subscribe(
(event: HttpEvent<any>) => {
if (event.type === HttpEventType.UploadProgress) {
     //console.log(event.total!);
   if (event.total! > 0) {
       (event as any).percent = (event.loaded / event.total!) * 100;
}
       item.onProgress!(event, item.file!);
} else if (event instanceof HttpResponse) {
     //console.log(event);
  if (event.body.code !== 200) {
        item.onError!('', item.file!);
        this.message.error(event.body.msg);
 } else {
       item.onSuccess!(event.body, item.file!, event);
       this.message.success('上传成功');
}
}
},
err => {
    //console.log(err);
    item.onError!(err, item.file!);
}
);
}

4)页面展示:

三、JS+html5版本

1)html:

<progress id="progressBar" value="0" max="100" style="width: 300px;"></progress>  //进程标签
<span id="percentage"></span><span id="time"></span>
<br /><br />
<input type="file" id="file" name="myfile" />
<input type="button" onclick="UpladFile()" value="上传" />
<input type="button" onclick="cancleUploadFile()" value="取消" />

2)js:

<script type="text/javascript">
let xhr;
let ot;//
let oloaded;
//上传文件方法
function UpladFile() {
   let fileObj = document.getElementById("file").files[0];           // js 获取文件对象
   let url = "http://192.168.108.24:30573/xxx/xxx/";                   // 接收上传文件的后台地址
  let form = new FormData();                                                    // FormData 对象
  form.append("mf", fileObj);                                                     // 文件对象

 xhr = new XMLHttpRequest(); // XMLHttpRequest 对象

 xhr.open("post", url, true);                      //post方式,url为服务器请求地址,true 该参数规定请求是否异步处理。
xhr.onload = uploadComplete; //请求完成
xhr.onerror = uploadFailed; //请求失败
xhr.upload.onprogress = progressFunction; //【上传进度调用方法实现】
xhr.upload.onloadstart = function () { //上传开始执行方法
ot = new Date().getTime(); //设置上传开始时间
oloaded = 0; //设置上传开始时,以上传的文件大小为0
};
xhr.send(form); //开始上传,发送form数据
}
//上传进度实现方法,上传过程中会频繁调用该方法
function progressFunction(evt) {
let progressBar = document.getElementById("progressBar");
let percentageDiv = document.getElementById("percentage");
// event.total是需要传输的总字节,event.loaded是已经传输的字节。如果event.lengthComputable不为真,则event.total等于0
if (evt.lengthComputable) {//
progressBar.max = evt.total;
progressBar.value = evt.loaded;
percentageDiv.innerHTML = Math.round(evt.loaded / evt.total * 100) + "%";
}

let time = document.getElementById("time");
let nt = new Date().getTime(); //获取当前时间
let pertime = (nt - ot) / 1000; //计算出上次调用该方法时到现在的时间差,单位为s
ot = new Date().getTime(); //重新赋值时间,用于下次计算
let perload = evt.loaded - oloaded; //计算该分段上传的文件大小,单位b
oloaded = evt.loaded; //重新赋值已上传文件大小,用以下次计算

//上传速度计算
let speed = perload / pertime;//单位b/s
let bspeed = speed;
let units = 'b/s';//单位名称
if (speed / 1024 > 1) {
speed = speed / 1024;
units = 'k/s';
}
if (speed / 1024 > 1) {
speed = speed / 1024;
units = 'M/s';
}
speed = speed.toFixed(1);
//剩余时间
let resttime = ((evt.total - evt.loaded) / bspeed).toFixed(1);
time.innerHTML = ',速度:' + speed + units + ',剩余时间:' + resttime + 's';
if (bspeed == 0)
time.innerHTML = '上传已取消';
}
//上传成功响应
function uploadComplete(evt) {
alert("上传成功!");
}
//上传失败
function uploadFailed(evt) {
alert("上传失败!");
}
//取消上传
function cancleUploadFile() {
xhr.abort();
}
</script>

注意:

若想用jQuery 中的ajax实现的话,jQuery的 ajax 方法没有关于 progress 事件的操作,此时需要调用的XMLHttpRequest对象是指定progress 事件。XMLHttpRequest对象,传送数据的时候,有一个progress事件,用来返回进度信息。

它分成上传和下载两种情况
1)下载的progress事件属于XMLHttpRequest对象
2)上传的progress事件属于XMLHttpRequest.upload对象。

 

 posted on 2020-11-29 16:09  楼顶铁板烧  阅读(624)  评论(0编辑  收藏  举报