`
lingyun246
  • 浏览: 37479 次
  • 来自: 北京
社区版块
存档分类
最新评论

html5 File API实现带有进度提示的文件上传

    博客分类:
  • html
阅读更多
转:
Html5终于解决了上传文件的同时显示文件上传进度的老问题。现在大部分的网站用Flash去实现这一功能,还有一些网站继续采用Html <form>with enctype=multipart/form-data,但是需要修改服务器端可用才能显示给用户文件上传的进度。本质上你需要做的工作是在服务器端接收一个文件时,你发送给它一个字节流,所以你需要知道你已经接收到多少字节并以某种方式传达这些信息给客户端浏览器,在这个过程一直在不断的进行文件的上传。这种方式运行的非常好,不像Flash上传那这样充满了问题(特别是处理大文件上传的时候),然而这种方法是相当复杂的并且听起来不容易理解,因为你本质上是接管了整个服务器端的处理(获取字节流的时候)同时包括了在服务器端实现multipart/form-data协议,伴随一系列的其他事情。

使用Html5 上传文件
XMLHttpRequest 在Html5 规范中已经有全新的变化,规定了XMLHttpRequest Level 2规范(目前最新版本)包含下列新的特性:

处理字节流,例如作为上传或者下载的File,Blob,FormData对象
上传或者下载中的进度事件
跨站点请求
允许创建匿名请求
可以设置请求超时
在这篇文章中我们将能够更清楚的看到#1和#2两个特性。通常,上传文件用XMLHttpRequest并且提供上传进度信息给最终的用户,需要注意的是这种方式解决了不需要服务器端做任何改变,至少是目前处理multipart/form-data协议。所以服务器端的处理逻辑保留不变,这使得开发者适应这种技术相当容易。

enter image description here 图1:文件上传画面-准备上传 enter image description here 图2:显示上传完成画面

注意:上面的图片中,信息提示区域是提供给用户的:

当前选中文件的信息
文件名
文件大小
文件类型
上传完成多少的百分比进度条
上传速度或者上传带宽
距离上传完成大概还有多长时间
已上传文件大小
服务器端的响应
上面第6项或许看起来不重要,但事实上是相当重要的。因为我们用XMLHttpRequest,上传发生在后台,页面没有发生跳转等任何变化,所以对于你用它处理其他一些事情来说是一个非常好的特性。

Html5 Progress Event
对于Html5 Progress Events规范,Html5 Progess Events提供了下列与本次讨论相关的信息

total - 总的字节数
loaded - 到目前为止上传的字节数
lengthComputable - 可计算的已上传字节
请注意到我们需要用两个信息去计算要显示给用户的其他所有信息。要计算出来其他的信息通过上面我们得到信息是相当容易的,但是那需要一些额外的代码并且创建一个定时器。

Html5 Progress Event 应该是什么
考虑到有一部分人想更好的提供给用户所有的信息,所以Html5 Progress Event应该更好的满足需要,因为它给浏览器供应商提供这些额外信息是相当简单的,所以建议progress event应该修改成如下:

total - 总的字节数
loaded - 到目前为止上传的字节数
lengthComputable - 可计算的已上传字节
transferSpeed long类型
timeRemaining JavaScript 日期对象
Html5 上传 用XMLHttpRequest
浏览器支持情况

支持这一特性的浏览器最低版本

Firefox 4.0 beta 6
Chrome 6
Safari 5.02
IE 9 Beta and Opera 10.62 不支持这一特性

简单的示例
下面是一个完整的Html页面包含了实现文件上传并带有进度提示的JavaScript代码,只是实现了基本的功能,感兴趣的可以自己做扩展。 需要吧上传接口修改成自己服务的。


<!DOCTYPE html>
<html>
<head>
    <title>Upload Files using XMLHttpRequest - Minimal</title>
    <script type="text/javascript">
      function fileSelected() {
        var file = document.getElementById('fileToUpload').files[0];
        if (file) {
          var fileSize = 0;
          if (file.size > 1024 * 1024)
            fileSize = (Math.round(file.size * 100 / (1024 * 1024)) / 100).toString() + 'MB';
          else
            fileSize = (Math.round(file.size * 100 / 1024) / 100).toString() + 'KB';
          document.getElementById('fileName').innerHTML = 'Name: ' + file.name;
          document.getElementById('fileSize').innerHTML = 'Size: ' + fileSize;
          document.getElementById('fileType').innerHTML = 'Type: ' + file.type;
        }
      }
      function uploadFile() {
        var fd = new FormData();
        fd.append("fileToUpload", document.getElementById('fileToUpload').files[0]);
        var xhr = new XMLHttpRequest();
        xhr.upload.addEventListener("progress", uploadProgress, false);
        xhr.addEventListener("load", uploadComplete, false);
        xhr.addEventListener("error", uploadFailed, false);
        xhr.addEventListener("abort", uploadCanceled, false);
        xhr.open("POST", "upload.do");//修改成自己的接口
        xhr.send(fd);
      }
      function uploadProgress(evt) {
        if (evt.lengthComputable) {
          var percentComplete = Math.round(evt.loaded * 100 / evt.total);
          document.getElementById('progressNumber').innerHTML = percentComplete.toString() + '%';
        }
        else {
          document.getElementById('progressNumber').innerHTML = 'unable to compute';
        }
      }
      function uploadComplete(evt) {
        /* 服务器端返回响应时候触发event事件*/
        alert(evt.target.responseText);
      }
      function uploadFailed(evt) {
        alert("There was an error attempting to upload the file.");
      }
      function uploadCanceled(evt) {
        alert("The upload has been canceled by the user or the browser dropped the connection.");
      }
    </script>
</head>
<body>
  <form id="form1" enctype="multipart/form-data" method="post" action="Upload.aspx">
    <div class="row">
      <label for="fileToUpload">Select a File to Upload</label><br />
      <input type="file" name="fileToUpload" id="fileToUpload" onchange="fileSelected();"/>
    </div>
    <div id="fileName"></div>
    <div id="fileSize"></div>
    <div id="fileType"></div>
    <div class="row">
      <input type="button" onclick="uploadFile()" value="Upload" />
    </div>
    <div id="progressNumber"></div>
  </form>
</body>
</html>

原网站地址:http://my.oschina.net/u/1377774/blog/284703?fromerr=wd2TtzAP
分享到:
评论

相关推荐

    MVC中基于Ajax和HTML5实现文件上传功能

    在实际编程中,经常遇到实现文件上传并显示上传进度的功能,基于此目的,本文就为大家介绍不使用flash 或任何上传文件的插件来实现带有进度显示的文件上传功能。 基本功能:实现带有进度条的文件上传功能 高级功能:...

    react-hooks-multiple-file-upload:使用带有Axios和进度栏的Hooks示例来React多文件上传

    带有进度栏和Axios的React Hooks多文件上传示例 我们将使用Hooks创建一个React Multiple Files上传应用程序,该用户可以: 使用进度条查看每个文件的上传过程(百分比) 查看所有上传的文件 单击文件名时,下载...

    上传媒资文件至视频点播(aliyun-sdk-vod-upload) .zip

    * 1) 上传网络m3u8音视频文件时需要保证地址可访问,如果有权限限制,请设置带签名信息的地址,且保证足够长的有效期,防止地址无法访问导致上传失败 * 2) m3u8文件上传暂不支持进度回调 * * * 四、上传进度回...

    material-ui-image-upload:带有预览,Axios和进度栏的Material UI图像上载示例

    带有预览,Axios和进度栏的Material UI图像上载示例使用Preview to Rest API构建Material UI Image Upload示例。 React App使用和 File来发出HTTP请求,使用Material UI来显示进度条以及其他UI组件。 您还将显示图像...

    FileUploaderPlugin:简单的跨平台插件来上传文件

    产品特点带有标题和参数的分段文件上传一次上传多个文件上传请求进度反馈使用字节或文件路径上载文件设置自定义边界建立在NuGet上可用: ://www.nuget.org/packages/Plugin.FileUploader 安装到您的PCL项目和客户端...

    react-image-upload-preview:使用预览,进度栏,引导程序,Axios到Rest API的React Image Upload示例

    您还将显示图像信息的显示列表(带有下载URL)。 有关更多详细信息,请访问: 该React Client的Rest API服务器: 多练: 安全: 全栈CRUD 使用Node.js Express: 使用Spring Boot: React.js + Spring Boot + ...

    Google Android SDK开发范例大全(第3版) 5/5

    系统服务及研发的整合:网络搜索、联系人、音乐、应用程序、定制手机文件管理、记忆卡I/O存取、双向短信、闹钟服务、开机程序、来电通信互动、拜年短信、信息提醒、电池电量显示、进度显示、取得应用程序信息等。...

    delphi 开发经验技巧宝典源码

    0139 使用FileExists函数判断指定文件是否存在 90 0140 使用FileGetAttr函数返回文件的属性 90 0141 使用FileGetDate函数返回文件的修改日期 90 0142 使用FileWrite函数将缓冲区中的内容写入文件 91 4.10 ...

    Google Android SDK开发范例大全(第3版) 1/5

    系统服务及研发的整合:网络搜索、联系人、音乐、应用程序、定制手机文件管理、记忆卡I/O存取、双向短信、闹钟服务、开机程序、来电通信互动、拜年短信、信息提醒、电池电量显示、进度显示、取得应用程序信息等。...

    Google Android SDK开发范例大全(第3版) 4/5

    系统服务及研发的整合:网络搜索、联系人、音乐、应用程序、定制手机文件管理、记忆卡I/O存取、双向短信、闹钟服务、开机程序、来电通信互动、拜年短信、信息提醒、电池电量显示、进度显示、取得应用程序信息等。...

    Google Android SDK开发范例大全(第3版) 3/5

    系统服务及研发的整合:网络搜索、联系人、音乐、应用程序、定制手机文件管理、记忆卡I/O存取、双向短信、闹钟服务、开机程序、来电通信互动、拜年短信、信息提醒、电池电量显示、进度显示、取得应用程序信息等。...

    delphi 开发经验技巧宝典源码06

    0139 使用FileExists函数判断指定文件是否存在 90 0140 使用FileGetAttr函数返回文件的属性 90 0141 使用FileGetDate函数返回文件的修改日期 90 0142 使用FileWrite函数将缓冲区中的内容写入文件 91 4.10 ...

    FileCopyDemo:FileCopyManager

    Apple没有提供带有进度回调的文件复制操作的API。 开发人员必须获得此功能的唯一选择是使用较低级别的API,在这种情况下为copyfile(3)。 与往常一样,Apple的文档非常稀少,也没有关于如何使用此API来实现所需功能...

    xUtils3 demo

    带有缓存的请求示例: BaiduParams params = new BaiduParams(); params.wd = "xUtils"; // 默认缓存存活时间, 单位:毫秒.(如果服务没有返回有效的max-age或Expires) params.setCacheMaxAge(1000 * 60); Callback....

    asp.net知识库

    如何实现web页面的提示保存功能 在ASP.Net中两种利用CSS实现多界面的方法 如何在客户端调用服务端代码 页面一postback,它就显示页面的最顶端,怎样让它定位在某一位置? 如何保证页面刷新后的滚动条位置 清除网页...

    Visual C++ 编程资源大全(源码 窗体)

    open.zip 带位图预览的打开文件对话框(4KB)&lt;END&gt;&lt;br&gt;2,bmpdlg.zip 一个位图对话框类 (11KB)&lt;END&gt;&lt;br&gt;3,folder.zip 只显示文件夹信息的文件对话框(2KB)&lt;END&gt;&lt;br&gt;4,dir_pic.zip 文件目录搜集工具对话框(42...

    Oracle9i的init.ora参数中文说明

    请注意所有用户均可读取或写入 UTL_FILE_DIR 参数中指定的所有文件。 值范围: 任何有效的目录路径。 默认值: 无 plsql_v2_compatibility: 说明: 设置 PL/SQL 兼容级。如果设置为 FALSE, 将执行 PL/SQL V3 行为, ...

    aria2rpc:通过 Aria2 RPC 添加下载任务

    请注意,aria2 带有自己的脚本(位于aria2源文件树下的doc/xmlrpc/aria2rpc ),它在Ruby 中实现了完整的 XML-RPC API,如果您需要的不仅仅是添加下载链接,您可以检查一下。 参数示例: aria2rpc -cookie ' id=xxx...

Global site tag (gtag.js) - Google Analytics