SSE 技术如何实现服务端文件上传进度更新?
随着前端技术的不断发展,越来越多的应用需要上传文件功能。对于用户来说,上传大文件时常常感觉不到上传进度,既没有进度条,也没有百分比指示。为了提升用户体验,我们需要实时更新上传进度。本文将介绍使用 SSE 技术实现服务端文件上传进度更新的方法,以及如何将其应用到实际项目中。
SSE 技术简介
Server-Sent Events (SSE) 是一种全双工协议,允许浏览器和服务器之间建立可持久性连接,实现了从服务器向客户端的单向实时数据传输。相比于 WebSocket 技术,SSE 技术更加轻量级,不需要建立双向通信,只需要从服务器向客户端单向推送数据。因此,SSE 技术更加适合用于推送通知、实时更新等场景。
服务端实现 SSE 技术
服务端 SSE 技术的实现主要有两个步骤:建立 SSE 连接和发送 SSE 数据。
建立 SSE 连接
建立 SSE 连接需要设置响应头信息 Content-Type: text/event-stream,告诉浏览器需要建立 SSE 连接。然后,需要将连接保持住,设置响应头信息 Connection: keep-alive,并且每隔一定时间发送一个空数据 data: \n\n,避免连接断开。
// www.javascriptcn.com code example
app.get('/sse-upload', (req, res) => {
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
});
// Send a keep-alive message every 15 seconds
setInterval(() => {
res.write('data: \n\n');
}, 15000);
});发送 SSE 数据
服务端发送 SSE 数据采用的是 res.write() 方法。SSE 数据需要遵守一定的格式:
event: eventName表示事件名称,可以省略;data: dataContent表示数据内容,不能为空;\n\n表示结束符,必须要有。
例如,下面的代码实现了一个 SSE 数据的发送实例:
// www.javascriptcn.com code example
app.post('/upload', (req, res) => {
const filePath = path.join(__dirname, 'uploads', req.file.filename);
const fileStream = fs.createReadStream(filePath);
// Send SSE data
fileStream.on('data', (chunk) => {
const percent = Math.round(chunkIndex / totalChunks * 100);
res.write(`event: upload\n`);
res.write(`data: ${percent}%\n`);
res.write(`\n`);
});
fileStream.on('end', () => {
res.write(`event: upload\n`);
res.write(`data: 100%\n`);
res.write(`\n`);
res.end();
});
});前端实现 SSE 技术
前端实现 SSE 技术主要涉及到 SSE 连接的建立、数据的处理以及事件的绑定。
建立 SSE 连接
在前端需要使用 EventSource 类建立 SSE 连接。可以通过传入 SSE URL 来建立连接:
const sse = new EventSource('/sse-upload');建立 SSE 连接后,可以监听 open 和 error 事件,来处理连接建立成功和错误的情况:
sse.addEventListener('open', (event) => {
console.log('SSE connection has been established.');
});
sse.addEventListener('error', (event) => {
console.log('SSE connection has been closed.');
});数据的处理
服务端发送的 SSE 数据可以通过监听 message 事件来处理:
sse.addEventListener('message', (event) => {
const data = event.data;
// handle SSE data
});在服务端,SSE 数据的格式已经约定了,因此,在前端可以根据约定的格式处理数据,例如更新上传进度条:
sse.addEventListener('message', (event) => {
const data = event.data;
const match = data.match(/^data: (\d+)%$/);
if (match) {
const percent = match[1];
updateProgressBar(percent);
}
});事件的绑定
在处理 SSE 数据时,可能需要绑定一些事件,例如上传完成事件:
// www.javascriptcn.com code example
sse.addEventListener('message', (event) => {
const data = event.data;
const match = data.match(/^data: (\d+)%$/);
if (match) {
const percent = match[1];
updateProgressBar(percent);
if (percent === 100) {
// handle upload finished event
}
}
});应用到实际项目中
在实际项目中,我们可以将 SSE 技术应用于各种上传、下载场景,例如图片上传、文件下载、实时日志更新等。在上传下载场景中,SSE 技术可以实现实时更新进度条和状态信息,大大提升用户体验;在实时日志更新场景中,SSE 技术可以实现服务端日志输出到浏览器中,实时查看日志信息,方便调试。
本文介绍了使用 SSE 技术实现上传进度更新的方法。借助 SSE 技术,可以实现实时更新上传进度、上传完成事件等功能,提升用户体验。在实际项目中,我们可以将 SSE 技术应用到各种上传场景中,提升应用的实时性和用户体验。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d6a1eaa941bf7134c69bbe