当前位置: 首页 > wzjs >正文

济南建站服务商今天特大新闻

济南建站服务商,今天特大新闻,网站建设服务费标准,什么网站可以做相册视频🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志 🎐 个人CSND主页——Micro麦可乐的博客 🐥《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程,入门到实战 🌺《RabbitMQ》…

在这里插入图片描述

🌷 古之立大事者,不惟有超世之才,亦必有坚忍不拔之志
🎐 个人CSND主页——Micro麦可乐的博客
🐥《Docker实操教程》专栏以最新的Centos版本为基础进行Docker实操教程,入门到实战
🌺《RabbitMQ》专栏19年编写主要介绍使用JAVA开发RabbitMQ的系列教程,从基础知识到项目实战
🌸《设计模式》专栏以实际的生活场景为案例进行讲解,让大家对设计模式有一个更清晰的理解
🌛《开源项目》本专栏主要介绍目前热门的开源项目,带大家快速了解并轻松上手使用
✨《开发技巧》本专栏包含了各种系统的设计原理以及注意事项,并分享一些日常开发的功能小技巧
💕《Jenkins实战》专栏主要介绍Jenkins+Docker的实战教程,让你快速掌握项目CI/CD,是2024年最新的实战教程
🌞《Spring Boot》专栏主要介绍我们日常工作项目中经常应用到的功能以及技巧,代码样例完整
🌞《Spring Security》专栏中我们将逐步深入Spring Security的各个技术细节,带你从入门到精通,全面掌握这一安全技术
如果文章能够给大家带来一定的帮助!欢迎关注、评论互动~

前端AJAX请求进度监控指南详解与完整代码示例

  • 1. 前言
  • 2. 基于XMLHttpRequest的进度监控
    • 2.1 基础版文件上传监控
    • 2.2 增强版多事件监控
  • 3. 基于Fetch API 的进度监控
    • 3.1 Fetch API + ReadableStream实现下载监控
    • 3.2 Fetch API 上传进度监控(伪方案)
  • 4. Axios封装进度监控方案
    • 4.1 Axios 上传进度监控
    • 4.2 Axios 下载进度监控
    • 4.3 封装 Axios 实例
  • 5. 特殊场景处理技巧
    • 5. 1 分块上传监控
    • 5. 2 带宽计算与预估
  • 6. 结语

1. 前言

在日常 Web 开发中,AJAX(Asynchronous JavaScript and XML)被广泛用于异步请求数据,而无需刷新整个页面。然而,当涉及到上传下载文件或执行长时间运行的任务时,为了提升用户体验通常我们需要显示执行的进度条,那么监控请求的进度就变得尤为重要。

这里博主给大家讲解 XMLHttpRequestFetch API 以及 Axios封装 在进度监控上不同的实现方式

在这里插入图片描述

进度监控的核心场景 :
1. 大文件上传/下载
2. 实时数据传输(如视频流)
3. 长耗时API请求
4. 用户交互反馈优化


2. 基于XMLHttpRequest的进度监控

JavaScript 中,XMLHttpRequest 提供了 progress 事件,允许我们监听请求的进度。

2.1 基础版文件上传监控

<input type="file" id="fileInput">
<progress id="uploadProgress" value="0" max="100"></progress><script>
document.getElementById('fileInput').addEventListener('change', function(e) {const file = e.target.files[0];if (!file) return;const xhr = new XMLHttpRequest();const progressBar = document.getElementById('uploadProgress');xhr.upload.addEventListener('progress', (e) => {if (e.lengthComputable) {const percent = (e.loaded / e.total) * 100;progressBar.value = percent;console.log(`上传进度: ${percent.toFixed(1)}%`);}});xhr.addEventListener('load', () => {console.log('上传完成');});xhr.open('POST', '/upload', true);xhr.send(file);
});
</script>

2.2 增强版多事件监控

我们还可以集合 progress 进行多事件监控,如下代码:

function uploadWithProgress(file) {return new Promise((resolve, reject) => {const xhr = new XMLHttpRequest();// 上传进度监控xhr.upload.addEventListener('progress', (e) => {handleProgress('upload', e);});// 下载进度监控(当服务器返回大数据时)xhr.addEventListener('progress', (e) => {handleProgress('download', e);});xhr.addEventListener('error', reject);xhr.addEventListener('abort', reject);xhr.addEventListener('load', () => {if (xhr.status >= 200 && xhr.status < 300) {resolve(xhr.response);} else {reject(xhr.statusText);}});xhr.open('POST', '/upload');xhr.setRequestHeader('Content-Type', 'application/octet-stream');xhr.send(file);function handleProgress(type, e) {if (e.lengthComputable) {const percent = (e.loaded / e.total) * 100;console.log(`${type} progress: ${percent.toFixed(1)}%`);}}});
}

3. 基于Fetch API 的进度监控

3.1 Fetch API + ReadableStream实现下载监控

Fetch API 本身没有直接提供进度事件,但我们可以利用 ReadableStream 对响应体进行分段读取,从而计算已加载的字节数。

当第一次请求链接 await fetch(url) 的时候通过获取 headersContent-Length 返回的请求资源总大小,再结合 response.body.getReader() 来读取 body 内容来实现!

具体参考代码如下,小伙伴可以根据自身需求进行调整:

async function downloadLargeFile(url) {const response = await fetch(url);const reader = response.body.getReader();const contentLength = +response.headers.get('Content-Length');let receivedLength = 0;const chunks = [];while(true) {const {done, value} = await reader.read();if (done) break;chunks.push(value);receivedLength += value.length;const percent = (receivedLength / contentLength) * 100;console.log(`下载进度: ${percent.toFixed(1)}%`);}const blob = new Blob(chunks);return blob;
}// 使用示例
downloadLargeFile('/large-file.zip').then(blob => {const url = URL.createObjectURL(blob);const a = document.createElement('a');a.href = url;a.download = 'file.zip';a.click();});

3.2 Fetch API 上传进度监控(伪方案)

Fetch API 原生并不支持上传进度监控。不过可以采用将文件包装成一个自定义的 ReadableStream 来实现 “伪”上传进度监控
需要注意的是,由于各浏览器对 Request 流处理的支持程度不一,该方法可能并非在所有环境下都能稳定工作。博主建议非必要不要采用这种方式

<!DOCTYPE html>
<html lang="zh">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Fetch API 上传进度监控</title>
</head>
<body><input type="file" id="fileInput"><button onclick="uploadFile()">上传文件</button><progress id="progressBar" value="0" max="100"></progress><span id="progressText">0%</span><script>function uploadFile() {const fileInput = document.getElementById('fileInput');const file = fileInput.files[0];if (!file) {alert('请选择文件');return;}const progressBar = document.getElementById('progressBar');const progressText = document.getElementById('progressText');const total = file.size;let uploaded = 0;// 构造一个自定义的 ReadableStream 来包装文件流const stream = new ReadableStream({start(controller) {const reader = file.stream().getReader();function push() {reader.read().then(({ done, value }) => {if (done) {controller.close();return;}uploaded += value.byteLength;const percent = (uploaded / total) * 100;progressBar.value = percent;progressText.innerText = percent.toFixed(2) + '%';controller.enqueue(value);push();}).catch(error => {console.error('读取文件错误:', error);controller.error(error);});}push();}});// 使用 Fetch API 发送 POST 请求fetch('/upload', {method: 'POST',headers: {// 根据后端要求设置合适的 Content-Type// 注意:如果使用 FormData 上传文件,浏览器会自动设置 multipart/form-data'Content-Type': 'application/octet-stream'},body: stream}).then(response => response.json()).then(data => {console.log('上传成功:', data);alert('上传完成');}).catch(error => {console.error('上传失败:', error);alert('上传失败');});}</script>
</body>
</html>

注意事项

  • 上传进度:Fetch API 本身不提供上传进度事件,上述方法通过包装文件流来模拟上传进度,但并非所有浏览器都支持这种方式,稳定性可能不如 XMLHttpRequest
  • 内容类型:如果后端要求 multipart/form-data 格式,建议仍采用 XMLHttpRequest 或使用 FormData 对象,因为自定义流方式上传数据可能需要后端特殊处理

4. Axios封装进度监控方案

通过封装 Axios 请求,可以同时监听上传和下载的进度,提升用户体验,再次之前我们先来看看未封装前最原始的上传和下载是如何实现的~

4.1 Axios 上传进度监控

Axios 支持通过配置项 onUploadProgress 来监听上传进度。以下示例展示了如何使用 Axios 上传文件,并在页面上显示进度信息:

<!DOCTYPE html>
<html lang="zh">
<head><meta charset="UTF-8"><title>Axios 上传进度监控</title>
</head>
<body><h2>文件上传(Axios)</h2><input type="file" id="fileInput"><button onclick="uploadFile()">上传文件</button><br><progress id="uploadProgress" value="0" max="100" style="width: 300px;"></progress><span id="uploadText">0%</span><!-- 引入 Axios 库 --><script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script><script>function uploadFile() {const fileInput = document.getElementById('fileInput');const file = fileInput.files[0];if (!file) {alert('请选择文件');return;}const formData = new FormData();formData.append('file', file);axios.post('/upload', formData, {headers: {'Content-Type': 'multipart/form-data'},onUploadProgress: function (progressEvent) {if (progressEvent.lengthComputable) {const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total);document.getElementById('uploadProgress').value = percent;document.getElementById('uploadText').innerText = percent + '%';}}}).then(response => {alert('上传成功');console.log(response.data);}).catch(error => {alert('上传失败');console.error(error);});}</script>
</body>
</html>

代码解释:
使用 FormData 对象包装上传的文件;
通过 Axios 的 onUploadProgress 事件监听上传过程,并实时更新进度条和百分比显示。

4.2 Axios 下载进度监控

同理,Axios 还支持 onDownloadProgress 事件来监控文件下载进度。下面的示例展示了如何通过 Axios 下载文件并实时显示下载进度:

<!DOCTYPE html>
<html lang="zh">
<head><meta charset="UTF-8"><title>Axios 下载进度监控</title>
</head>
<body><h2>文件下载(Axios)</h2><button onclick="downloadFile()">下载文件</button><br><progress id="downloadProgress" value="0" max="100" style="width: 300px;"></progress><span id="downloadText">0%</span><!-- 引入 Axios 库 --><script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script><script>function downloadFile() {axios.get('/download', {responseType: 'blob',  // 指定响应数据类型为 BlobonDownloadProgress: function (progressEvent) {if (progressEvent.lengthComputable) {const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total);document.getElementById('downloadProgress').value = percent;document.getElementById('downloadText').innerText = percent + '%';}}}).then(response => {// 创建一个临时链接下载文件const url = window.URL.createObjectURL(new Blob([response.data]));const a = document.createElement('a');a.href = url;a.download = 'downloaded_file';document.body.appendChild(a);a.click();a.remove();window.URL.revokeObjectURL(url);}).catch(error => {alert('下载失败');console.error(error);});}</script>
</body>
</html>

代码解释:
1、我们通过 axios.get 请求下载文件,并设置 responseType 为 blob;
2、通过 onDownloadProgress 事件监听下载进度,并更新进度条;
3、下载完成后利用 Blob 和临时链接触发浏览器下载文件。

4.3 封装 Axios 实例

为了在项目中更方便地使用进度监控功能,可以将 Axios 进行封装。例如,我们可以创建一个 Axios 实例,并在请求配置中统一处理上传和下载进度

import axios from 'axios';// 请求配置
const axiosInstance = axios.create({onUploadProgress: progressEvent => {const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total);console.log(`上传进度: ${percent}%`);},onDownloadProgress: progressEvent => {const percent = Math.round((progressEvent.loaded * 100) / progressEvent.total);console.log(`下载进度: ${percent}%`);}
});// 封装上传方法
async function axiosUpload(file) {const formData = new FormData();formData.append('file', file);try {const response = await axiosInstance.post('/upload', formData, {headers: {'Content-Type': 'multipart/form-data'}});return response.data;} catch (error) {console.error('上传失败:', error);throw error;}
}

使用时,在页面中调用封装方法即可,这样通过封装后的 Axios 实例,我们可以在项目中更加方便地复用进度监控功能。


5. 特殊场景处理技巧

通常在一些特殊场景下,针对进度监控我们还需要一些处理技巧,这里博主分享两个分别是 分块上传监控带宽计算与预估

5. 1 分块上传监控

async function chunkedUpload(file, chunkSize = 1024 * 1024) {const chunks = Math.ceil(file.size / chunkSize);let uploadedChunks = 0;for (let i = 0; i < chunks; i++) {const start = i * chunkSize;const end = Math.min(start + chunkSize, file.size);const chunk = file.slice(start, end);await axios.post('/upload-chunk', chunk, {headers: {'Content-Range': `bytes ${start}-${end-1}/${file.size}`},onUploadProgress: e => {const chunkPercent = (e.loaded / e.total) * 100;const totalPercent = ((uploadedChunks + e.loaded) / file.size) * 100;console.log(`分块进度: ${chunkPercent.toFixed(1)}%`);console.log(`总进度: ${totalPercent.toFixed(1)}%`);}});uploadedChunks += chunk.size;}
}

5. 2 带宽计算与预估

let startTime;
let lastLoaded = 0;xhr.upload.addEventListener('progress', e => {if (!startTime) startTime = Date.now();const currentTime = Date.now();const elapsed = (currentTime - startTime) / 1000; // 秒const speed = e.loaded / elapsed; // bytes/sconst remaining = (e.total - e.loaded) / speed; // 剩余时间console.log(`传输速度: ${formatBytes(speed)}/s`);console.log(`预计剩余时间: ${remaining.toFixed(1)}`);
});function formatBytes(bytes) {const units = ['B', 'KB', 'MB', 'GB'];let unitIndex = 0;while (bytes >= 1024 && unitIndex < units.length - 1) {bytes /= 1024;unitIndex++;}return `${bytes.toFixed(1)} ${units[unitIndex]}`;
}

6. 结语

本篇文章介绍了如何在前端请求中监控上传和下载进度,并提供了完整的前端和后端代码示例。通过合理运用这些技术,开发者可以构建出具有专业级进度反馈的Web应用,显著提升用户在处理大文件传输时的体验。

希望能帮助小伙伴们在项目中更好地处理大文件传输,提高用户体验!

如果本本章内容对您有所帮助,希望 一键三连 给博主一点点鼓励,如果您有任何疑问或建议,请随时留言讨论!


在这里插入图片描述

http://www.dtcms.com/wzjs/526732.html

相关文章:

  • 重庆知名网站建设公司网络广告宣传怎么做
  • 贵阳网站设计企业网站排名优化软件哪家好
  • 网站个人备案做企业网站跨境电商网站
  • 做旅行义工网站蚁网站seo推广计划
  • 分站城市网站如何做seoseo工资待遇 seo工资多少
  • 杰迅山西网站建设新网站秒收录技术
  • 如果做动态网站开发 以下中山网站建设公司
  • 怎么夸客户网站做的好关键词在线试听
  • 做网站放广告百度信息流投放
  • 法律垂直问答网站怎样做网络营销方式有哪些分类
  • 旅游网站首页制作seo搜索引擎优化排名报价
  • 做环氧地坪工程网站百度快照排名
  • 国外真实新闻网站西安seo顾问培训
  • 哪儿提供邯郸做网站seo优化教程培训
  • 做设计在哪个网站投递简历sem推广是什么
  • 伽师网站建设百度网络营销中心app
  • wordpress短代码调用文章标题萧山区seo关键词排名
  • php与mysql网站开发...网站建设外包
  • 深圳门户网站建设专业靠谱的seo收费
  • 服装企业网站内容规划品牌策划包括哪几个方面
  • 宁波设计网页公司手机优化什么意思
  • 做网站销售的换工作最新资讯热点
  • 淘宝网站设计价格西安百度关键词包年
  • 免费网络电话排行seo搜索排名影响因素主要有
  • 哪个网站做x展架比较好 知乎网站seo课程
  • 企业需要做网站吗百度网页版首页
  • 建设网站备案不通过怎么办理企业关键词推广
  • 营商环境建设局网站广州网站建设方案优化
  • 公司网站seo外包搜索引擎优化网站排名
  • 安卓wordpress搜索引擎关键词优化技巧