如何在Express的/test路由触发事件,让返回的HTML接收数据,不使用Socket.IO
实现方案
核心用SSE(Server-Sent Events) 实现,这是HTML5原生标准,Express、前端JS都原生支持,不需要引入Socket.IO这类第三方库,完全符合你的需求。
服务端代码改造
你需要新增一个专门的SSE长连接路由,同时维护当前连接的客户端列表,触发事件时给所有在线客户端推送数据:
const express = require('express') const app = express() const port = 3000 // 存储所有连接到/test页面的SSE客户端响应对象 let sseClients = new Set() // 原有的/test路由,返回html页面 app.get('/test', (req, res) => { res.sendFile(__dirname + "\\myhtml.html") }) // 新增SSE长连接路由,用来和前端维持持续通信 app.get('/test/events', (req, res) => { // 设置SSE要求的固定响应头 res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive' }) // 把当前客户端加入连接列表 sseClients.add(res) // 客户端断开连接时自动清理 req.on('close', () => { sseClients.delete(res) }) }) // 你需要的触发事件方法,任意业务逻辑里调用即可推送数据给所有在线的/test页面 function fireMyThing(data) { sseClients.forEach(client => { // 严格遵循SSE消息格式:event指定事件名,data传数据,末尾两个换行标识本次消息结束 client.write(`event: mything\n`) client.write(`data: ${JSON.stringify(data)}\n\n`) }) } // 测试示例:服务端触发事件,和你伪代码里的page.fire效果完全一致 // 你可以在任意业务逻辑节点调用这个方法 setTimeout(() => { fireMyThing({one: 2}) }, 3000) // 页面打开3秒后推送测试数据 app.listen(port, () => { console.log(`服务运行在 http://localhost:${port}`) })
myhtml.html前端代码实现
用原生EventSource对接SSE接口,监听方式和你期望的写法完全匹配:
<!DOCTYPE html> <html> <body> <script> // 和服务端建立SSE长连接 const eventSource = new EventSource('/test/events') // 监听自定义的mything事件,和你要的写法完全一致 eventSource.addEventListener('mything', (event) => { const res = JSON.parse(event.data) console.log(res) // 输出 {one: 2} }) // 可选:错误处理逻辑 eventSource.addEventListener('error', (err) => { console.error('连接出错', err) eventSource.close() }) </script> </body> </html>
方案说明
- 无任何第三方依赖,完全基于原生能力实现
- SSE天生支持自定义事件名、断开自动重连,非常适合服务端单向推送数据的场景
- 如果后续需要双向通信,可以改用原生WebSocket实现,也不需要引入第三方库
内容的提问来源于stack exchange,提问作者sld
相关产品推荐
相关产品推荐

