注意事项:
1、携带cookie需要客户端的Ajax对象属性withCredentials值为true
2、携带cookie需要服务端配置头信息Access-Control-Allow-Credentials为true
3、携带cookie需要服务端的配置头信息Access-Control-Allow-Origin为具体域名,不是 *
服务端3000客户端html代码:
<body>
<div id="container">
<form id="form1">
<input id="username" name="username" type="text" placeholder="请输入账号">
<input id="pwd" name="pwd" type="password" placeholder="请输入密码">
<input type="button" id="btn1" value="提交">
<input type="button" id="btn2" value="检查登录状态">
</form>
</div>
<script>
var btn1 = document.getElementById('btn1');
var btn2 = document.getElementById('btn2');
var form1 = document.getElementById('form1');
btn1.addEventListener('click', () => {
var formData = new FormData(form1);
var xhr = new XMLHttpRequest();
xhr.open('post', 'http://localhost:3001/login');
// 发送请求时,携带cookie信息
xhr.withCredentials = true;
xhr.send(formData);
// 监听服务器端给予的响应
xhr.onload = function() {
console.log(xhr.responseText);
}
})
btn2.addEventListener('click', () => {
var xhr = new XMLHttpRequest();
xhr.open('get', 'http://localhost:3001/check');
// 发送请求时,携带cookie信息
xhr.withCredentials = true;
xhr.send();
xhr.onload = function() {
console.log(xhr.responseText);
}
})
</script>
</body>
服务器3000代码:(服务3000就是为了客户端代码可以正常运行)
const express = require('express');
const path = require('path');
const app = express();
app.use(express.static(path.join(__dirname, 'public')));
app.listen(3000);
console.log('3000已启动');
服务端3001代码:(express-session模块的引入)
const express = require('express');
const formidable = require('formidable');
// 实现session功能
var session = require('express-session');
const app = express();
// 实现session功能
app.use(session({
// 通过设置的 secret 字符串,来计算 hash 值并放在 cookie 中,使产生的 signedCookie 防篡改
// 可以随意取,建议不连贯的字符串
secret: 'keyboard cat',
// 当客户端并行发送多个请求时,其中一个请求在另一个请求结束时对session进行修改覆盖并保存。
resave: false,
// 初始化session时是否保存到存储。
saveUninitialized: false
}));
app.use((req, res, next) => {
// 注意:如果跨域请求中涉及到cookie信息传递,值不可以为*号 比如是具体的域名信息
res.header('Access-Control-Allow-Origin', 'http://localhost:3000');
// 允许客户端使用哪些请求方法访问我
res.header('Access-Control-Allow-Methods', 'get,post');
// 允许客户端发送跨域请求时携带cookie信息
res.header('Access-Control-Allow-Credentials', true);
// 使用中间件不要忘记next来放行
next();
})
app.post('/login', (req, res) => {
// 创建表单解析对象
var form = formidable.IncomingForm();
// 解析表单
form.parse(req, (err, fields, file) => {
console.log(fields);
// 对象解构
const { username, pwd } = fields;
console.log(username);
console.log(pwd);
// 用户信息比对
if (username == 'xixi.com' && pwd == '123123') {
// 设置session
req.session.isLogin = true;
res.send({ message: '登录成功' });
} else {
res.send({ message: '登录失败' });
}
})
})
app.get('/check', (req, res) => {
// 判断用户是否处于登录状态
if (req.session.isLogin) {
res.send({ message: '处于登录状态' })
} else {
res.send({ message: '处于未登录状态' })
}
})
app.listen(3001);
console.log('3001已启动');
如果不给客户端和服务器端添加属性配置,在点击检查登录状态时,会显示未登录状态