使用express-sse时遇res.flush is not a function及响应头错误求助
解决express-sse使用中的两个错误问题
错误原因梳理
res.flush is not a function:你之前在POST请求里调用sse.send时,express-sse试图操作当前POST请求的响应对象,但普通POST响应并非SSE长连接对象,没有flush方法,导致服务器崩溃。Cannot set headers after they are sent to the client:先返回res.status().json()后,POST请求的响应已经完全发送,之后再调用sse.send会尝试修改已发送的响应头,触发冲突。
正确解决步骤
1. 单独配置SSE订阅端点
先创建SSE实例,并提供一个GET接口让客户端订阅实时通知:
const express = require('express'); const router = express.Router(); const SSE = require('express-sse'); const Order = require('../models/Order'); // 替换为你的订单模型路径 const Table = require('../models/Table'); // 替换为你的餐桌模型路径 // 初始化SSE实例 const sse = new SSE(); // 新增订阅端点,客户端通过这个GET接口接收通知 router.get('/subscribe-order-updates', sse.init);
2. 修改createOrder接口逻辑
订单创建成功后,直接用SSE实例的send方法广播消息,和POST请求的响应完全分离:
router.post("/createOrder", async (req, res) => { try { let { orderItems, email, orderStatus, paymentStatus, orderType, orderAmount, tableId } = req.body; // 创建订单记录 const order = await Order.create({ orderItems, email, orderStatus, paymentStatus, orderType, orderAmount }); // 更新餐桌的当前订单(直接存完整order对象更合理) await Table.updateOne( { tableId: tableId }, { $push: { currentOrders: order }, $set: { status: 'occupied' } } ); // 给所有订阅的客户端推送订单创建通知 sse.send(order, "order_created"); // 正常返回POST请求的响应 res.status(200).json({ message: "Order Placed", orderId: order._id }); } catch (err) { console.error(err); res.status(500).json({ error: "Server Error!" }); } });
3. 前端订阅示例(参考)
客户端可以用EventSource来订阅这个SSE流:
const orderEventSource = new EventSource('/subscribe-order-updates'); orderEventSource.addEventListener('order_created', (event) => { const newOrder = JSON.parse(event.data); console.log('收到新订单通知:', newOrder); // 这里可以加弹窗、更新订单列表等逻辑 });
内容的提问来源于stack exchange,提问作者potatoprogrammer
相关产品推荐
相关产品推荐

