【发布时间】:2021-03-12 23:27:56
【问题描述】:
我无法通过 fetch 发送 cookie。我read 表示对于跨域请求,您必须使用credentials: 'include'。但这仍然没有给我饼干。
获取 html 文档
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div>fetch on load</div>
<script>
fetch('http://localhost:4001/sayhi', { credentials: 'include' })
.then((res) => {
return res.text();
})
.then((text) => {
console.log('fetched: ' + text);
})
.catch(console.log);
</script>
</body>
</html>
服务器文件:
const express = require('express');
const mongoose = require('mongoose');
const session = require('express-session');
const MongoStore = require('connect-mongo')(session);
const app = express();
const cors = require('cors');
app.use(cors());
app.use((req, res, next) => {
console.log(req.path);
// this will log a cookie when several
// requests are sent through the browser
// but 'undefined' through `fetch`
console.log('cookie in header: ', req.headers.cookie);
next();
});
app.use(
session({
secret: 'very secret 12345',
resave: true,
saveUninitialized: false,
store: new MongoStore({ mongooseConnection: mongoose.connection }),
})
);
app.use(async (req, res, next) => {
console.log(`${req.method}: ${req.path}`);
try {
req.session.visits = req.session.visits ? req.session.visits + 1 : 1;
return next();
} catch (err) {
return next(err);
}
});
app.get('/sayhi', (req, res, next) => {
res.send('hey');
});
(async () =>
mongoose.connect('mongodb://localhost/oneSession', {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: true,
}))()
.then(() => {
console.log(`Connected to MongoDB set user test`);
app.listen(4001).on('listening', () => {
console.log('info', `HTTP server listening on port 4001`);
});
})
.catch((err) => {
console.error(err);
});
运行 console.log('cookie in header: ', req.headers.cookie); 的中间件为每个获取请求返回 undefined。
我相信每个 fetch 请求也在创建一个新会话,因为没有设置 cookie。
如何通过 fetch 获取要发送的 cookie?
更新:部分答案
到目前为止,我认为添加这些帮助:
//instead of app.use(cors());
app.use(
cors({
credentials: true,
origin: 'http://localhost:5501', // your_frontend_domain, it's an example
})
);
app.use((req, res, next) => {
`res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Origin', 'http://127.0.0.1:5501');` // your_frontend_domain, it's an example
next()
});
但我还有一个问题:
在 devtools 中,我转到“网络”并刷新 html 文件以再次发送请求。在那里我看到了响应标头。我可以看到 Set-Cookie 标头已发送,但有一个黄色三角形警告。
它说将sameSite 设置为true。
我需要在会话选项中添加cookie: { sameSite: 'none' }
app.use(
session({
secret: 'very secret 12345',
resave: true,
cookie: { sameSite: 'none' },
saveUninitialized: false,
store: new MongoStore({ mongooseConnection: mongoose.connection }),
})
);
在我这样做之后,cookie 收到了一个新的黄色三角形警告,说我需要在 cookie-secure: true 上设置另一个选项。但这意味着只有通过 HTTPS 发送的请求才会起作用。但我正在开发中,无法通过 https 发送。
【问题讨论】:
标签: node.js mongodb express cookies fetch