node.js - 节点快速会话不跨页面保存
问题描述
我不知道为什么当我转到 localhost:8080 时它会保存会话(似乎是),但是当我转到下一个 URL localhost:8080/me 时,会话又是空的。
const express = require("express");
const app = express();
const port = 8080;
const router = express.Router();
const session = require('express-session');
app.use(session({
secret: 'work hard',
resave: true,
saveUninitialized: false
}))
app.get("/", function(req,res, next){
req.session.myname = "nathan";
console.log(req.session.myname);
});
app.get("/me", function(req,res, next){
console.log(req.session.myname);
});
app.listen(port, () => console.log(`Example app listening on port ${port}!`))
当我尝试下面第一个贡献者(在答案中)所示的 app.sendStatus 方法时,它可以工作,但如果我使用 ajax 则不行?
$("#register").on("click", function(){
$.ajax({url: "http://localhost:8080/"});
});
$("#me").on("click", function(){
$.ajax({url: "http://localhost:8080/me"});
});
解决方案
原因是您没有向客户端发送带有set-cookie标头的响应。
Set-Cookie HTTP 响应头用于将 cookie 从服务器发送到用户代理,因此用户代理可以稍后将它们发送回服务器。
您可以使用res.sendStatus()
,res.send()
等。res.end()
向res.json()
客户端发送响应。
例如
app.js
:
const express = require('express');
const app = express();
const port = 8080;
const router = express.Router();
const session = require('express-session');
const fs = require('fs');
const path = require('path');
app.use(
session({
secret: 'work hard',
resave: true,
saveUninitialized: false,
}),
);
app.get('/', function(req, res, next) {
req.session.myname = 'nathan';
console.log(req.session.myname);
const htmlContent = fs.readFileSync(path.resolve(__dirname, './public/app.html')).toString();
res.send(htmlContent);
});
app.get('/me', function(req, res, next) {
console.log(req.session.myname);
res.sendStatus(200);
});
app.get('/ajax', function(req, res) {
console.log('req.session.myname: ', req.session.myname);
res.sendStatus(200);
});
app.listen(port, () => console.log(`Example app listening on port ${port}!`));
完成此操作后,您的客户端(可以是浏览器)将收到这些响应标头:
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/plain; charset=utf-8
Content-Length: 2
ETag: W/"2-nOO9QiTIwXgNtWtBJezz8kv3SLc"
set-cookie: connect.sid=s%3A-QI2kuY8IlxdAZw96xqG_npmuKwFhg0s.tKcPZgcHhHvXG0kqgKzwzJJ7kn2JkPOMG9R%2FyQaJwPw; Path=/; HttpOnly
Date: Mon, 23 Dec 2019 06:00:24 GMT
Connection: keep-alive
浏览器会自动设置cookie。然后,你转到下一个/me
路由,浏览器会自动发送这个带有请求头的 cookie。
例如
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cache-Control: no-cache
Connection: keep-alive
Cookie: connect.sid=s%3A-QI2kuY8IlxdAZw96xqG_npmuKwFhg0s.tKcPZgcHhHvXG0kqgKzwzJJ7kn2JkPOMG9R%2FyQaJwPw
Host: localhost:8080
Pragma: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36
在您的服务器端/me
控制器中,express-session
中间件将解析 cookie,您将获得myname
fromreq.session.myname
属性的值。
更新:
./public/app.html
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
</head>
<body>
<main>
app
<button id="me">Click Me</button>
</main>
<script
src="https://code.jquery.com/jquery-3.4.1.min.js"
integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
crossorigin="anonymous"
></script>
<script>
window.onload = function() {
$('#me').on('click', function() {
$.ajax({ url: 'http://localhost:8080/ajax' }).then(() => {
console.log('success');
});
});
};
</script>
</body>
</html>
您也可以获得 的值myname
。这是服务器端日志:
Example app listening on port 8080!
nathan
req.session.myname: nathan
推荐阅读
- azure - 未处理的错误:TypeError:无法读取未定义的属性“地图”
- python - 强制 sqlite3(在 python 上)按顺序存储数据
- dns - 如何在启用多存储功能的 prestashop 中将子文件夹别名为根域?
- mysql - XAMPP 中的错误 - MySQL 意外关闭
- javascript - 如何索引firebase中的引用字段?
- sql - SSIS 多播 - 按特定顺序执行
- javascript - 将参数传递给 React (API) 中的函数
- javascript - 如何使用 ComponentDidUpdate?
- oracle - Oracle 在创建存储过程时出错。ORA-22905: 无法访问非嵌套表项中的行
- javascript - 在使用Javascript向表中添加行的函数中添加on-change