在前端开发中,实时更新进度条是一种非常常见的需求。通常情况下,我们可以使用 Ajax 或 WebSocket 等技术实现实时更新进度条。但是,随着 Server-sent Events 技术的成熟和普及,利用 Server-sent Events 实现实时更新进度条也变得越来越简单。
什么是 Server-sent Events
Server-sent Events(简称 SSE)是一种基于 HTTP 的服务器推送技术。和 WebSocket 类似,SSE 也可以实现服务器和客户端之间的实时双向通信,但是相比 WebSocket,SSE 更加轻量级,更加适合用于实现单向的服务器推送。
SSE 的实现原理非常简单,就是在客户端通过 EventSource 对象向服务器发送一个 HTTP GET 请求,服务器返回一个包含 event-stream 数据的 HTTP 响应,并通过 Content-Type 头部指定为 text/event-stream。客户端通过监听 message 事件来接收从服务器推送过来的数据。
利用 SSE 实现进度条的实时更新
利用 SSE 实现进度条的实时更新非常简单,只需要在服务器端定时向客户端推送进度数据即可。下面是一个简单的示例代码:
// javascriptcn.com 代码示例 // 服务器端代码 const http = require('http') const fs = require('fs') http.createServer((req, res) => { if (req.url === '/progress') { res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive' }) let progress = 0 const timer = setInterval(() => { progress += 10 if (progress <= 100) { res.write(`data: ${JSON.stringify({ progress })}\n\n`) } else { clearInterval(timer) res.end() } }, 1000) } else { res.writeHead(200, {'Content-Type': 'text/html'}) fs.createReadStream(__dirname + '/index.html').pipe(res) } }).listen(3000) console.log('Server running at http://localhost:3000/')
// javascriptcn.com 代码示例 <!-- 客户端代码 --> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Server-sent Events Progress Bar</title> </head> <body> <div id="progress-bar" style="width: 0%; height: 20px; background-color: #00bcd4;"></div> <script> const progressBar = document.getElementById('progress-bar') const source = new EventSource('/progress') source.onmessage = (event) => { const data = JSON.parse(event.data) progressBar.style.width = `${data.progress}%` } </script> </body> </html>
上面的代码实现了一个简单的进度条,每秒钟增加 10%,直到进度条达到 100%。在客户端页面中,我们使用 EventSource 对象连接到 /progress 路径,然后监听 message 事件,每次接收到数据后更新进度条的宽度。
总结
利用 Server-sent Events 实现进度条的实时更新非常简单,只需要在服务器端定时向客户端推送进度数据即可。相比于 Ajax 和 WebSocket,SSE 更加轻量级,适合用于实现单向的服务器推送。如果你需要实现实时更新进度条的功能,不妨尝试一下使用 SSE。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/655b66bbd2f5e1655d58ca6f