我制作了一个完全剥离的测试API和前端来演示此问题,这将至少在将API部署到Heroku时发生:
这是整个API。 app.js:
const express = require('express')
const cors = require('cors')
const app = express()
const router = express.Router()
// This was supposed to help with problems from Heroku's Vegur
// I also tried app.enable('trust proxy') syntax
app.set('trust proxy', true)
// allow cors
const corsOptions = {
'origin': true,
'credentials': true,
}
app.options('*', cors(corsOptions))
app.use(cors(corsOptions))
const port = process.env.PORT || 3000
app.use(router)
router.get('/', function (req, res) {
res.send('test ready')
})
router.post('/', function (req, res) {
res.cookie("testCookie", {
led: "zepplin",
pink: "floyd",
}, {
encode: String
})
res.send("cookie set")
})
app.listen(port, () => {
console.log(`listening on port ${port}`)
})
的package.json:
{
"name": "testapp",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node app.js",
},
"author": "",
"license": "ISC",
"dependencies": {
"cors": "^2.8.3",
"express": "^4.15.2"
}
}
这就是整个前端。一个php单行程,让它去,index.php:
<?php header( 'Location: /index.html' ) ; ?>
和index.html:
<!DOCTYPE html>
<html>
<head>
<script>
function fetchAPI() {
fetch(your_heroku_api_url, {
method: 'POST',
credentials: 'include',
})
.then((response) => {
return response.text()
})
.then((text) => {
console.log({res: text})
})
.catch((er) => {
console.log({error: er})
})
}
</script>
</head>
<body>
<button onclick=fetchAPI()>FETCH REQUEST</button>
</body>
</html>
如果我使用Postman点击那条POST路线,我会得到预期的行为。将设置cookie。如果我是从Chrome这样做的话。我不。我确实获得了set-cookie标头,但Chrome不会设置该Cookie:
所以我很困惑。我在一个更复杂的应用程序中遇到了同样的问题,实现了与此类似的身份验证令牌。它只是使用上面的Express的res.cookie()方法,它也会到达浏览器,也会被忽略。此外,我的会话设置为client-sessions。这些cookie表现出相同的不成功行为。偶尔,我甚至会看到请求中发送的cookie,我不知道这是怎么回事,因为它永远不会在浏览器中设置。同样,当在本地运行在不同的端口上或者Postman访问本地或Heroku API时,一切都会工作。
答案 0 :(得分:1)
不幸的是,ajax调用中的响应不会影响浏览器中的cookie。
如果您想更改浏览器的cookie,您需要从响应中提取标头并将其设置为浏览器cookie。