文件上传进度提示

简介: 当上传的文件相对较大时,用户可能需要等待较长的时间,这个时候前端如果没有任何提示的话,体验不是很好,如果有上传进度提示,就会好很多。而要在上传过程实时显示上传进度,则需要已上传的大小和文件总大小。

需求

当上传的文件相对较大时,用户可能需要等待较长的时间,这个时候前端如果没有任何提示的话,体验不是很好,如果有上传进度提示,就会好很多。而要在上传过程实时显示上传进度,则需要已上传的大小和文件总大小。

前提

  • 请求是异步的。因为要实时获取到上传的进度,则请求需是异步的,如果是同步的话,会直到请求完成才能获取到响应。

实现

这里总结的主要是js方面,至于进度条的显示,有的UI框架,比如semantic就自带了进度条的实现,直接使用即可,没有的话也可以自己用改变div宽度等方式实现,这里不赘述。

如何获取到文件的上传进度?
Javascript的XMLHttpRequest提供了一个progress事件,这个事件会返回文件已上传的大小和总大小,根据这两个值,就可以计算上传进度了,关于这个方法,在《Javascript高级程序设计(第3版)》21章第3节中有叙述,有这本书在手的可以看一下。下面贴一下代码。

XMLHttpRequest:progress事件

使用Javascript的XMLHttpRequest的progress事件,实现示例代码为:

var formData = new FormData(); 
formData.append("file", document.getElementById('file').files[0]); 
formData.append("token", token_value); // 其他参数按这样子加入

var xhr = new XMLHttpRequest();
xhr.open('POST', '/uploadurl');
// 上传完成后的回调函数
xhr.onload = function () {
  if (xhr.status === 200) {
  console.log('上传成功');
  } else {
   console.log('上传出错');
  }
};
// 获取上传进度
xhr.upload.onprogress = function (event) {
  if (event.lengthComputable) {
    var percent = Math.floor(event.loaded / event.total * 100) ;
    // 设置进度显示
    $("#J_upload_progress").progress('set progress', percent);
  }
};
xhr.send(formData);
复制代码

关于FormData和XMLHttpRequest, 可以搜下W3C了解详情。

jQuery封装的xhr

jQuery封装了xhr的实现, 也可以使用jQueryajax获得上传进度,示例代码:

var formData = new FormData(); 
formData.append("file", document.getElementById('file').files[0]); 
formData.append("token", token_value); 

$.ajax({ 
    url: "/uploadurl", 
    type: "POST", 
    data: formData, 
    processData: false, // 不要对data参数进行序列化处理,默认为true
    contentType: false, // 不要设置Content-Type请求头,因为文件数据是以 multipart/form-data 来编码
    xhr: function(){
        myXhr = $.ajaxSettings.xhr();
        if(myXhr.upload){
          myXhr.upload.addEventListener('progress',function(e) {
            if (e.lengthComputable) {
              var percent = Math.floor(e.loaded/e.total*100);
              if(percent <= 100) {
                $("#J_progress_bar").progress('set progress', percent);
                $("#J_progress_label").html('已上传:'+percent+'%');
              }
              if(percent >= 100) {
                $("#J_progress_label").html('文件上传完毕,请等待...');
                $("#J_progress_label").addClass('success');
              }
            }
          }, false);
        }
        return myXhr;
    },
    success: function(res){ 
        // 请求成功
    },
    error: function(res) {
        // 请求失败
        console.log(res);
    }
}); 
 复制代码

关于jQuery ajax的xhr, 具体可查看W3C。

vue-resource

var formData = new FormData();
formData.append('token', token_value);  // csrf token
formData.append("works", document.getElementById('file').files[0]); // file
var url = $("#R_batch_upload_url").val();

vm.$http.post(url, formData, {
  progress: (e) => {
    if (e.lengthComputable) {
      var percent = Math.floor(e.loaded/e.total*100);
      if(percent <= 100) {
        $("#J_progress_bar").progress('set progress', percent);
        $("#J_progress_label").html('已上传:'+percent+'%');
      }
      if(percent >= 100) {
        $("#J_progress_label").html('文件上传完毕,提交表单中,请等待...');
        $("#J_progress_label").addClass('success');
      }
    }
  }
})
.then((res) => {
  if(res.ok && res.status === 200) {
    window.location.href = window.location.href;
  }
}, (res) => {
  if(res.status === 400) {
      $("#J_progress_label").html('文件格式错误,请修改后重试');
      $("#J_progress_label").addClass('warning');
      console.log(res);
      vm.errMsg.show = true;
      vm.errMsg.msg = res.body.msg;
      vm.canSend = true;
      // TODO hide the loader dimmer
      $("#J_upload_batch").dimmer("hide");
    } else {
      $("#J_progress_label").html(res.statusText);
      $("#J_progress_label").addClass('warning');
    }
});复制代码

七牛云储存

有些文件过大,后台会采取上传到七牛,再获取其地址保存到数据库的方式,这种方式的话,前端可以使用上面两种方式XMLHttpRequest或jQuery封装的xhr实现发送请求及获取上传进度,如果需要更复杂的上传数据处理,也可以考虑使用七牛提供的配套Javascript SDK实现,若是只需要进度提示的话,并不需要引入七牛JS SDK。

另外一点,上传成功后设置重定向到网站某页面的话,可能会报错跨域重定向。

相关链接




原文发布时间为:2018年07月02日

作者:掘金

本文来源:掘金 如需转载请联系原作者

相关文章
|
4月前
axios 上传显示进度
axios 上传显示进度
|
3月前
|
存储 资源调度 JavaScript
vue上传文件时显示上传进度
vue上传文件时显示上传进度
39 0
成功解决百度网盘下载文件时遇到 下载总进度一直处于99.9%,显示一直下载不下来的问题
成功解决百度网盘下载文件时遇到 下载总进度一直处于99.9%,显示一直下载不下来的问题
成功解决百度网盘下载文件时遇到 下载总进度一直处于99.9%,显示一直下载不下来的问题
|
10月前
|
JavaScript
form表单提交后,页面弹出成功或者失败的信息
form表单提交后,页面弹出成功或者失败的信息
113 0
|
11月前
|
存储 API 开发工具
Bug日志(三)-获取本地图片后上传失败
原来为了能给用户提供对文件的更多控制并限制文件混乱,Android Q改变了应用程序访问设备外部存储上文件的方式,例如存储在路径/ sdcard中的文件。Android Q继续使用READ_EXTERNAL_STORAGE和WRITE_EXTERNAL_STORAGE权限,这些权限对应于存储面向用户的运行时权限。但是,默认情况下targetSdkVersion设置为Android Q的应用(以及manifest清单开启属性来启动这个变更的应用)会获得一个沙盒视图到外部存储。此类应用程序只能看到其特定于应用程序的目录和特定媒体类型,因此应用程序不需要请求任何其他用户权限。
|
11月前
|
移动开发 安全 JavaScript
上传ipa到appstore的步骤说明
我们平时在开发原生的ios app的时候,有苹果电脑在手,上传ipa文件到苹果开发者中心比较简单,直接在xcode上就可以实现了。
|
数据安全/隐私保护 开发者 iOS开发
2023最新上传ipa到appstore的步骤说明
在2023年这个时间里,使用uniapp开发app的人已经非常多,uniapp可以打包多端应用,包括打包ios应用,打包的IOS文件是ipa后缀的文件。 这个文件我们无法直接在苹果开发者中心上传,它需要使用mac安装一些工具,比如xcode才能上传,这个门槛让windows电脑的开发者望而却步,这里我介绍如何不用mac电脑也能上传的方法。
373 0
2023最新上传ipa到appstore的步骤说明
|
安全 Linux 数据安全/隐私保护
2022最新上传ipa到appstore的步骤说明
最近有人提出问题,说IOS7怎么在APP store中下载软件,好多软件都提示需要ios8及以上才可以下载,而App Store里下载又不会提供给你旧版本,难倒ios7就必须升级才能下载吗?对此本人在网上查了好多资料也做了好多测试,大多数说的都是升级系统(这纯属废话,要是升级系统还用问你啊),终于皇天不负有心人,经过多次测试,我找到了一个解决办法,其实真的是非常简单,废话也不多说了,方法就是,把你的AppleId的用户名及密码让你的亲朋好友用他的苹果手机或者iPad登录(当然他的设备必须是高版本的)后先下载到他的设备上,这样你的AppleId就会记录下你的购买记录,接下来你就可以拿自己的低版本
2022最新上传ipa到appstore的步骤说明
|
JavaScript 前端开发
干货 | web自动化总卡在文件上传和弹框处理上?
在有些场景中,需要上传文件,而 Selenium 无法定位到弹出的文件框,以及网页弹出的提醒。这些都是需要特殊的方式来处理。 input 标签使用自动化上传,先定位到上传按钮,然后 send_keys 把路径作为值给传进去. 如图所示,是企业微信文件上传的页面 定位到标签为 input,type 为 file 的元素信息,然后使用 send_keys 把文件路径作为值给传进去。 ![](h
|
JSON 前端开发 JavaScript
上传文件返回数据提示下载
上传文件返回数据提示下载