zoukankan      html  css  js  c++  java
  • spring mvc + xmlHttpRequest2.0 实现无刷新上传文件,带进度条和剩余时间

    1、springmvc支持文件上传,需要在spring-mvc.xml配置文件中加上下面的一段话:

    <!-- 支持上传文件 -->  
        <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/> 
    

    2、下面介绍下XMLHttpRequest2.0

      最早,微软在IE 5引进了这个接口。因为它太有用,其他浏览器也模仿部署了,ajax操作因此得以诞生。

      但是,这个接口一直没有标准化,每家浏览器的实现或多或少有点不同。HTML 5的概念形成后,W3C开始考虑标准化这个接口。2008年2月,就提出了XMLHttpRequest Level 2 草案。

    这个XMLHttpRequest的新版本,提出了很多有用的新功能,将大大推动互联网革新。本文就对这个新版本进行详细介绍。

      老版本的XMLHttpRequest对象有以下几个缺点:

        * 只支持文本数据的传送,无法用来读取和上传二进制文件。

        * 传送和接收数据时,没有进度信息,只能提示有没有完成。

        * 受到"同域限制"(Same Origin Policy),只能向同一域名的服务器请求数据

      新版本的XMLHttpRequest对象,针对老版本的缺点,做出了大幅改进:   

        * 可以设置HTTP请求的时限。

        * 可以使用FormData对象管理表单数据。

        * 可以上传文件。

        * 可以请求不同域名下的数据(跨域请求)。

        * 可以获取服务器端的二进制数据。

        * 可以获得数据传输的进度信息。

      新版XMLHttpRequest对象,不仅可以发送文本信息,还可以上传文件。假定files是一个"选择文件"的表单元素(input[type="file"]),我们将它装入FormData对象。

    var formData = new FormData();
    for (var i = 0; i < files.length;i++) {
      formData.append('files[]', files[i]);
    }
    

      然后,发送这个FormData对象

    xhr.send(formData);
    

    3、代码实现

    废话不多说,上代码:

    前端页面代码:

    <!DOCTYPE html>
    <html>
    
    <head>
        <meta charset="UTF-8">
        <title>XMLHttpRequest上传文件进度实现</title>
        <script type="text/javascript">
        var xhr;
        var ot; //
        var oloaded;
        //上传文件方法
        function UpladFile() {
            var fileObj = document.getElementById("uploadForm"); // js 获取文件对象
            var url = "http://192.168.0.116:8080/partnersys/service/uploadFile"; // 接收上传文件的后台地址 
    
            var form = new FormData(fileObj); // FormData 对象
    
            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) {
    
            var progressBar = document.getElementById("progressBar");
            var 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) + "%";
            }
    
            var time = document.getElementById("time");
            var nt = new Date().getTime(); //获取当前时间
            var pertime = (nt - ot) / 1000; //计算出上次调用该方法时到现在的时间差,单位为s
            ot = new Date().getTime(); //重新赋值时间,用于下次计算
    
            var perload = evt.loaded - oloaded; //计算该分段上传的文件大小,单位b       
            oloaded = evt.loaded; //重新赋值已上传文件大小,用以下次计算
    
            //上传速度计算
            var speed = perload / pertime; //单位b/s
            var bspeed = speed;
            var 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);
            //剩余时间
            var resttime = ((evt.total - evt.loaded) / bspeed).toFixed(1);
            time.innerHTML = ',速度:' + speed + units + ',剩余时间:' + resttime + 's';
            if (bspeed == 0)
                time.innerHTML = '上传已取消';
        }
        //上传成功响应
        function uploadComplete(evt) {
            //服务断接收完文件返回的结果
            //    alert(evt.target.responseText);
            alert("上传成功!");
        }
        //上传失败
        function uploadFailed(evt) {
            alert("上传失败!");
        }
        //取消上传
        function cancleUploadFile() {
            xhr.abort();
        }
        </script>
    </head>
    
    <body>
        <progress id="progressBar" value="0" max="100" style=" 300px;"></progress>
        <span id="percentage"></span><span id="time"></span>
        <br />
        <br />
        <form id="uploadForm" method="post" enctype="multipart/form-data">
            <input type="file" id="file" name="myfile" /><!-- input标签的name属性用于post传输,作为表单的键值,后台通过键值获取序列化后的表单数据。name属性值和springmvc中的“@RequestParam(value = "myfile", required = true)”的value值相同,通过该值反序列化成springmvc的MultipartFile对象 -->
            <input type="button" onclick="UpladFile()" value="上传" />
            <input type="button" onclick="cancleUploadFile()" value="取消" />
        </form>
    </body>
    
    </html>
    

     后端java代码:

    @RequestMapping(value = "/uploadFile",method = RequestMethod.POST)
    	public void upload(@RequestParam(value = "myfile", required = true) MultipartFile file, HttpServletRequest request,
    			HttpServletResponse response)
    	{
    		String path = request.getSession().getServletContext().getRealPath("uploadFile");
    		String fileName = file.getOriginalFilename();
    		System.out.println("文件上传路径为:" + path);
    		File targetFile = new File(path, fileName);
    		if (!targetFile.exists())
    		{
    			targetFile.mkdirs();
    		}
    		// 保存
    		try
    		{
    			file.transferTo(targetFile);
    		}
    		catch (Exception e)
    		{
    			e.printStackTrace();
    		}
    	}
    	
    

      

      

  • 相关阅读:
    [luogu p1164] 小A点菜
    [luogu p5018] 对称二叉树
    [luogu p1305] 新二叉树
    [luogu p1030] 求先序排列
    [luogu p1087] FBI树
    [luogu p1449] 后缀表达式
    [luogu p1160] 队列安排
    [luogu p1057] 传球游戏
    有趣的问题系列-主元素问题
    [luogu p1192] 台阶问题
  • 原文地址:https://www.cnblogs.com/iwideal/p/6938863.html
Copyright © 2011-2022 走看看