0

The following is the example code with problems in CORS.

index.html, being served on localhost:3000 by a static file server:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <link rel="icon" href="/favicon.ico">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script>
    async function post() {
      const res = await fetch('http://localhost:3001', {
        method: 'POST',
        body: '{"msg":1}',
        headers: {
          'Access-Control-Allow-Origin': 'http://localhost:3000',
          'Content-Type': 'text/plain'
        },
        mode: 'cors'
      })
      console.log(await res.text())
    }
  </script>
</head>

<body>
  <button onclick="post()">POST</button>
</body>

</html>
// server.js using express
import express from 'express'
const server = express()
server.options('*', (req, res) => {
    res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000') // lower-case doesn't work either
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
    res.setHeader('Access-Control-Allow-Credentials', 'true')
    res.setHeader('Access-Control-Allow-Headers', 'Content-Type')
    res.send();
})
server.post('/', (req, res) => {
    console.log('POST /')
    res.send('OK')
})
server.listen(3001, () => {
    console.log('listening')
})

On the client side, the POST message is meant to be a simple request, but the browser sends a preflight OPTIONS message. On the server side, the server accepts the origin and methods, but the browser still gives this error message:

Access to fetch at 'http://localhost:3001/' from origin 'http://localhost:3000' has been blocked by CORS policy: Request header field access-control-allow-origin is not allowed by Access-Control-Allow-Headers in preflight response.

The HTTP messages in Wireshark: Wireshark Screenshot

Jackoo
  • 117
  • 1
  • 1
  • 12
  • Unrelated: FWIW, it's "browser", although I think I'm going to use "blowser" from now on, especially when it's IE. – Dave Newton May 24 '23 at 14:05
  • You're sending a header in the fetch that isn't in the allowed headers config; have you tried normalizing that at least? – Dave Newton May 24 '23 at 14:07
  • 1
    You should not manually set the `Access-Control-Allow-Origin` in your request in `index.html`. Just remove that line. – Evert May 24 '23 at 18:33

1 Answers1

-1

Thanks to @Evert, I've found what's wrong in the code.
For the client side, the 'Access-Control-Allow-Origin': 'http://localhost:3000' should be removed in the header. Then the POST will not cause a preflight request.
For the server side, res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000') should be added to the post handler. Then the browser will not throw the Access to fetch ... has been blocked by CORS policy error.

Jackoo
  • 117
  • 1
  • 1
  • 12