kwhitley / itty-router

A little router.
MIT License
1.75k stars 78 forks source link

CORS Error on POST request #70

Closed aligzl closed 2 years ago

aligzl commented 2 years ago

I am getting CORS error on post route as below

router.post('/login', async (request) => {
  const content = await request.json()
  return new Response(JSON.stringify(content), {
    headers: {
      'Access-Control-Allow-Origin': '*',
      'Content-type': 'application/json',
      'Accept': '*/*'
    }
  })
})

But there are no issue if i do GET with same options except content

kwhitley commented 2 years ago

Well not sure what's going on (because I muck my way through CORS myself), but it's def not an issue with itty-router itself, as I do full CORS stuff (POST included) on https://slick.af (which uses itty).

That said, CORS is a freaking annoying pain in general IMO, and although I've figured it out several times (and just again recently) I still haven't added a good CORS solution to itty-router-extras, but it's on the short list!

I generally tackle CORS with the following setup:

  1. upstream CORS handler for OPTIONS requests/responses.
    router.options('*', cors)
  2. add a downstream handler that embeds the CORS headers in outgoing responses (like you've done) - but after the handle, rather than on a request-by-request basis as it just leaves [much] cleaner route handlers:
    
    // disclaimer: pseudocode

router .handle(request, env) .then(response => { response.headers.set('Access-Control-Allow-Origin', 'whatever') // and other CORS headers

return response

}) .catch(error) // error from itty-router-extras



Will circle back to this when I release something, and please add more info if you find the solution!

By the way, definitely check out `itty-router-extras`, as it has a lot of little helper functions to making routing code shorter/more readable (including two things that would help you here, `json` and `withContent`).

```js
import { Router } from 'itty-router'
import { json, withContent } from 'itty-router-extras'

// define router and then here's your code, assuming downstream injection of CORS:

router.post('/login', withContent, ({ content }) => json(content))

// withContent (asynchronously parses body content into request.content)
// json (returns Response with appropriate JSON headers set and stringifies content/argument)
towfiqi commented 2 years ago

Those who are struggling with cors+ittyrouters, check out the solution provided here: https://github.com/kwhitley/itty-router-extras/discussions/16