效果图:

实现:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>fetch测试</title>
<link rel="stylesheet" href="/css/element.css">
<script src="/js/vue.min.js"></script>
<script src="/js/element.js"></script>
<script src="/js/jquery-3.5.1.min.js"></script>
<style>
body {
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="fetchApp">
<div style="margin: 200px auto;width: fit-content;display: flex;flex-direction: column;justify-content: center;">
<div style="margin-bottom: 50px;">
<el-progress type="circle" :percentage="count" :status="count==100?'success':''"></el-progress>
</div>
<div>
下载速率:{{speed>1024?parseInt(speed/1024*100)/100:speed}} {{speed>1024?'MB/s':'KB/s'}}
</div>
<el-button type="primary" @click="download">{{btnName}}</el-button>
</div>
</div>
<script>
new Vue({
el: '#fetchApp',
data () {
return {
btnName:'下载测试',
count:0,
speed:0,
time:0,
}
},
mounted () {
},
methods: {
async download(){
// get请求格式
let response = await fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits');
// post请求格式
// let response = await fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits',{
// method: 'POST',
// headers: {
// 'Content-Type': 'application/json;charset=utf-8'
// },
// body: JSON.stringify(user)
// });
const reader = response.body.getReader();
// 获得总长度(length)
const contentLength = +response.headers.get('content-length')
console.log(response.headers.get('content-length'));
// 读取数据
let receivedLength = 0; // 当前接收到了这么多字节
let chunks = []; // 接收到的二进制块的数组(包括 body)
while(true) {
const {done, value} = await reader.read();
if (done) {
break;
}
// 第一次时间戳为0,不测速
if(this.time){
// 获取下载当前数据所花费的时间
let ms = Date.now() - this.time
console.log(ms,value.length);
// 计算下载速度(KB/s)
this.speed = parseInt((value.length/(1024*8))/ms*1000)
// 保存当前的时间戳
this.time = Date.now()
}else{
this.time = Date.now()
}
chunks.push(value);
receivedLength += value.length;
this.count = parseInt(receivedLength/1572.24)
console.log(`Received ${receivedLength} of ${contentLength}`)
}
// 将块连接到单个 Uint8Array
let chunksAll = new Uint8Array(receivedLength);
let position = 0;
for(let chunk of chunks) {
chunksAll.set(chunk, position);
position += chunk.length;
}
// 解码成字符串
let result = new TextDecoder("utf-8").decode(chunksAll);
let commits = JSON.parse(result);
console.log(commits);
}
}
})
</script>
</body>
</html>