如何修复 Express Route 处理程序中丢失的 SocketIO 会话数据?
How Do You Fix SocketIO Session Data Missing In Express Route Handler?
我正在尝试在 nodejs 服务器上的 Express 和 SocketIO 之间共享会话数据。我在网上研究了如何在 https://socket.io/docs/v3/faq/#Usage-with-express-session
上实现它
注意:底部的前端和后端代码
任何时候我访问主页 http://localhost:5000 套接字连接成功并且会话包含 myData socketio初始连接中设置的值
SocketIO 控制台输出
Session {
cookie: {
path: '/',
_expires: null,
originalMaxAge: null,
httpOnly: true,
secure: true
},
myData: 'hello world'
}
然而,当一个请求发送到 http://localhost:5000/api/download 时控制台输出在Express 处理程序不包含会话中的 myData 值。
这表明即使 socketIO 正在保存会话数据,它也不会与 Express 共享。
Express 处理程序控制台输出
Session {
cookie: {
path: '/',
_expires: null,
originalMaxAge: null,
httpOnly: true,
secure: true
}
}
我在网上找遍了,好像也想不通。 socketIO 文档也没有帮助。
我还在 Whosebug 上尝试了其他解决方案,但 none 似乎有效。
- How to share sessions with Socket.IO 1.x and Express 4.x?
- socket.io and session?
这个问题是我最后一次寻求帮助解决问题的尝试。
谢谢
我的代码为前端和后端设置
前端 HTML: (index.html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1"
crossorigin="anonymous"
/>
<title>File Download Progress</title>
</head>
<body class="vh-100 w-2">
<div class="d-flex flex-column align-items-center vh-100">
<div>
<div class="d-flex flex-column align-items-center mt-5">
<h1 class="m-5">File Download Progress</h1>
<button class="m-1 w-100 btn btn-success" id="dl-btn">
Download
</button>
</div>
</div>
</div>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js"
integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW"
crossorigin="anonymous"
></script>
<script src="./socket.io.min.js"></script>
<script src="./app.js"></script>
</body>
</html>
前端:(app.js)
const downloadBtn = document.getElementById("dl-btn");
const socket = io("http://localhost:5000");
socket.on("connected", () => {
console.log("server connected");
});
downloadBtn.addEventListener("click", () => {
window.location = "http://localhost:5000/api/download";
});
后端:
import express from "express";
import session from "express-session";
import { createServer } from "http";
import { Server } from "socket.io";
import cors from "cors";
import bodyParser from "body-parser";
import asyncHandler from "express-async-handler";
const app = express();
const server = createServer(app);
const io = new Server(server, {
cors: {
origin: "http://localhost:3000",
methods: ["GET", "POST"],
},
});
const port = 5000;
const corsOptions = {
origin: "http://localhost:3000",
optionsSuccessStatus: 200,
};
const sessionMiddleware = session({
secret: "keyboard cat",
resave: false,
saveUninitialized: true,
cookie: { secure: true },
});
app.use(cors(corsOptions));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(sessionMiddleware);
io.use((socket, next) => {
sessionMiddleware(socket.request, socket.request.res || {}, next);
});
app.get("/api/", (req, res) => {
res.send("API is running");
});
app.get(
"/api/download",
asyncHandler(async (req, res) => {
console.log(req.session);
res.send("hello");
})
);
io.on("connection", (socket) => {
socket.emit("connected");
console.log("client connected");
const session = socket.request.session;
session.myData = "hello world";
session.save();
console.log(session);
});
server.listen(port, () => {
console.log(`listening at http://localhost:${port}`);
});
经过大量调查,我相信我已经找到了问题所在(而且比我想象的要简单得多)。
我注意到每个请求(websocket 和 http)都会生成一个新的会话 ID。我认为这个问题的原因是因为您为您的 cookie 设置了 secure:true
,但我相信您是 运行 通过 http 而不是 https。
清除所有 cookie,将安全选项设置为 false(对于生产环境,您很可能希望它为 true)并再次 运行 您的应用程序,看看是否获得了预期的结果。
我正在尝试在 nodejs 服务器上的 Express 和 SocketIO 之间共享会话数据。我在网上研究了如何在 https://socket.io/docs/v3/faq/#Usage-with-express-session
上实现它注意:底部的前端和后端代码
任何时候我访问主页 http://localhost:5000 套接字连接成功并且会话包含 myData socketio初始连接中设置的值
SocketIO 控制台输出
Session {
cookie: {
path: '/',
_expires: null,
originalMaxAge: null,
httpOnly: true,
secure: true
},
myData: 'hello world'
}
然而,当一个请求发送到 http://localhost:5000/api/download 时控制台输出在Express 处理程序不包含会话中的 myData 值。 这表明即使 socketIO 正在保存会话数据,它也不会与 Express 共享。
Express 处理程序控制台输出
Session {
cookie: {
path: '/',
_expires: null,
originalMaxAge: null,
httpOnly: true,
secure: true
}
}
我在网上找遍了,好像也想不通。 socketIO 文档也没有帮助。 我还在 Whosebug 上尝试了其他解决方案,但 none 似乎有效。
- How to share sessions with Socket.IO 1.x and Express 4.x?
- socket.io and session?
这个问题是我最后一次寻求帮助解决问题的尝试。
谢谢
我的代码为前端和后端设置
前端 HTML: (index.html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1"
crossorigin="anonymous"
/>
<title>File Download Progress</title>
</head>
<body class="vh-100 w-2">
<div class="d-flex flex-column align-items-center vh-100">
<div>
<div class="d-flex flex-column align-items-center mt-5">
<h1 class="m-5">File Download Progress</h1>
<button class="m-1 w-100 btn btn-success" id="dl-btn">
Download
</button>
</div>
</div>
</div>
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js"
integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW"
crossorigin="anonymous"
></script>
<script src="./socket.io.min.js"></script>
<script src="./app.js"></script>
</body>
</html>
前端:(app.js)
const downloadBtn = document.getElementById("dl-btn");
const socket = io("http://localhost:5000");
socket.on("connected", () => {
console.log("server connected");
});
downloadBtn.addEventListener("click", () => {
window.location = "http://localhost:5000/api/download";
});
后端:
import express from "express";
import session from "express-session";
import { createServer } from "http";
import { Server } from "socket.io";
import cors from "cors";
import bodyParser from "body-parser";
import asyncHandler from "express-async-handler";
const app = express();
const server = createServer(app);
const io = new Server(server, {
cors: {
origin: "http://localhost:3000",
methods: ["GET", "POST"],
},
});
const port = 5000;
const corsOptions = {
origin: "http://localhost:3000",
optionsSuccessStatus: 200,
};
const sessionMiddleware = session({
secret: "keyboard cat",
resave: false,
saveUninitialized: true,
cookie: { secure: true },
});
app.use(cors(corsOptions));
app.use(bodyParser.urlencoded({ extended: true }));
app.use(sessionMiddleware);
io.use((socket, next) => {
sessionMiddleware(socket.request, socket.request.res || {}, next);
});
app.get("/api/", (req, res) => {
res.send("API is running");
});
app.get(
"/api/download",
asyncHandler(async (req, res) => {
console.log(req.session);
res.send("hello");
})
);
io.on("connection", (socket) => {
socket.emit("connected");
console.log("client connected");
const session = socket.request.session;
session.myData = "hello world";
session.save();
console.log(session);
});
server.listen(port, () => {
console.log(`listening at http://localhost:${port}`);
});
经过大量调查,我相信我已经找到了问题所在(而且比我想象的要简单得多)。
我注意到每个请求(websocket 和 http)都会生成一个新的会话 ID。我认为这个问题的原因是因为您为您的 cookie 设置了 secure:true
,但我相信您是 运行 通过 http 而不是 https。
清除所有 cookie,将安全选项设置为 false(对于生产环境,您很可能希望它为 true)并再次 运行 您的应用程序,看看是否获得了预期的结果。