前后端交互 - 文件上传 ( 进度条 ) 及 XML

本文详细介绍了使用Ajax实现文件上传过程中进度条展示的方法,包括如何监听上传开始、上传中、上传成功、上传失败等事件,以及如何计算上传速度并显示在前端页面上。

上传进度条

说到前后端交互,上传文件就是极为常见的情景。
为了方便用户来接文件上传的进度,通常情况下都会带上文件传输的进度条。
区别只是样式的美丑。

ajax 中的 upload 方法

进度条的修改及速度计算 与 上传文件是同时进行。
ajax 的 upload 方法为我们提供了 读取文件进度 的一系列方法。

  • upload.onloadstart
	
	xhr.upload.onloadstart = function(){
		console.log("开始上传")
	}
	
  • upload.onprogress
	
	xhr.upload.onprogress = function(evt){
		console.log("上传中…");
		// 当前文件上传的大小 evt.loaded
		// 需要传输的大小 evt.total
	}
	
  • upload.onload

	xhr.upload.onload = function(){
		console.log("上传成功")
	}

  • upload.onerror

	xhr.upload.onerror = function(){
		console.log("上传失败")
	}

  • upload.onloadend
	// 不管是上传成功 还是 失败 都算作上传完成
	xhr.upload.onloadend = function(){
		console.log("上传完成")
	}

  • upload.onabort

	xhr.upload.onabort = function(){
		console.log("传输终止")
	}

  • abort

	xhr.abort(); //取消上传
	

progress ( 进度条 )

前端页面准备
	
	<input type="file" name="" id="myfile">
    进度: <progress value="1" max="100"></progress>
            <span class="percent">0%</span>
    速度:<span class="speed">0b/s</span>
    <button>开始上传</button>
    <button>取消上传</button>
    
前端JS代码

	let xhr = new XMLHttpRequest();
	let btns = document.querySelectorAll("button");
        
	btns[0].onclick = function () {

		let file = document.querySelector("#myfile").files[0];
        let form = new FormData();

        form.append("img", file);

        xhr.open("post", "/upload", true);
        xhr.onload = function () {
            // 获取返回的 数据(来自后端)
            console.log(xhr.responseText)
		}
            
		let stime; // 开始的节点时间
        let sloaded; // 开始的节点进度
        xhr.upload.onloadstart = function(){
        	console.log("开始上传")
            stime = new Date().getTime();
            sloaded = 0; 
		}

		xhr.upload.onprogress = function(evt){
			console.log("上传中…");
            // 当前文件上传的大小 evt.loaded
            // 需要传输的大小 evt.total

            // 取整 (小数点后几位)
            let percent = ((evt.loaded / evt.total)*100).toFixed()
            document.querySelector("progress").value = percent;
            document.querySelector(".percent").innerHTML = percent + "%";
                
            // 上传速度
            let endTime = new Date().getTime();
                
            // 1. 时间差
            let dTime = (endTime - stime)/1000;
                
            // 2. 上传文件大小
            let dloaded = evt.loaded - sloaded;

			// 3. 当前文件大小 / 时间差
            let speed = dloaded / dTime;
				
			stime = new Date().getTime();
            sloaded = evt.loaded;

            // 单位处理
            let unit = "b/s";
            if (speed / 1024 > 1) {  
            	unit = "kb/s";
                speed = speed / 1024 
            }
            if (speed / 1024 > 1) {
                unit = "mb/s";
                speed = speed / 1024
            }
            if (speed / 1024 > 1) {
                unit = "gb/s";
                speed = speed / 1024
            }

            document.querySelector(".speed").innerHTML = speed.toFixed(2) + unit;
                
		}

        xhr.upload.onload = function(){
            console.log("上传成功")
        }

        xhr.upload.onerror = function(){
            console.log("上传失败")
		}

		xhr.upload.onloadend = function(){
			console.log("上传完成")
			document.querySelector(".speed").innerHTML = "0 b/s";
		}

		xhr.send(form)
	}

	btns[1].onclick = function(){
		// 取消 上传
        xhr.abort();
	}

后端路由准备

	router.post("/upload",async ctx=>{
	    // console.log(ctx.request.body)
	    // .img  是因为页面 上传时候 添加的属性名为img
	    // console.log(ctx.request.files.img)
	    ctx.body = "接收成功";
	})


XML

是后端返回到页面的一种特殊格式的数据。
前端接收到后的数据 可以通过document 去调用获取数据。

后端路由准备
	router.get("/xml",ctx=>{
    // 接口文档:   接口: /xml  !DOCTYPE HTML
 	// 记得设置请求头,
 	// 否则前端接收到的是一整串的字符,控制台输出接收数据为 null
    // ctx.set("content-type","text/xml");
    ctx.body = `<?xml version='1.0' encoding='utf-8'?> 
                    <books>
                        <nodejs>   
                            <name>node实战</name> 
                            <price>56元</price>        
                        </nodejs> 
                        
                        <vue>
                            <name>vue实战</name>
                            <price>59元</price>
                        </vue>
                    </books>
                `;
	})
前端JS代码

xml格式的需要设置请求头,接收数据的方式转变为 xhr.responseXML


	document.querySelector("button").onclick = function(){
		let xhr = new XMLHttpRequest();
		xhr.open("get","/xml",true);
		// 后端不设置头部时 前端的处理方式
		// 客户端设置  响应报头的 content-type
        xhr.overrideMimeType("text/xml");
		xhr.onload = function(){
			console.log(xhr.responseXML); // 等同于 document
            let name = xhr.responseXML.getElementsByTagName("name")[0].innerHTML;
            console.log(name);
		}
		xhr.send();
	}

XML返回数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值