简体   繁体   中英

Node API on Heroku sends set-cookie headers, but Chrome won't set them (Postman, however, will)

I made a completely stripped down test API and frontend to demonstrate this issue, which will take place when at least the API is deployed to Heroku:

This is the whole 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"
  }
}

And this is the entire frontend. A php one-liner to make it go, index.php:

<?php header( 'Location: /index.html' ) ;  ?>

And 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>

If I hit that POST route with Postman, I get the intended behavior. The cookies will be set. If I do so from Chrome. I do not. I do get the set-cookie header, but Chrome will not set that cookie:

chrome 开发工具网络选项卡

So I'm pretty stuck. I have an auth token implemented similar to this in a more complex app suffering from the same issue. It just uses Express's res.cookie() method like above, it also arrives at the browser, it will also be ignored. Further I have my sessions set up with client-sessions . Those cookies exhibit the same unsuccessful behavior. Occasionally, I will even see the cookie sent in the request and I have no idea how that is happening since it is never being set in the browser. Again there, everything will work when run locally on separate ports or if the local or Heroku API is accessed by Postman.

Unfortunately response in ajax call doesn't affect cookie in browser.

If you want to change the cookie of the browser, you need to extract header from the response and set it to browser cookie.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM