My application uses a bookmarklet, and I need to allow CORS for MyRouteR
so my bookmarklet code can use this route for AJAX requests.
In my first draft of config/routes I gave MyRouteR
support for only one request method, PUT. But it turned out (duh) that I'd need to support the OPTIONS method as well, which browsers use for CORS preflight requests.
I ended up with the following in config/routes:
/myroute MyRouteR PUT OPTIONS
I was kind of hoping there would be some relevant machinery in the Template Haskell that processes config/routes so that the addition of OPTIONS to this route's method list would automagically result in CORS support, but no dice. Not the end of the world, but it would have made sense and felt elegant that way.
To make CORS work, I gave the route an OPTIONS handler:
optionsMyRouteR :: Handler RepPlain
optionsMyRouteR = do
addHeader "Access-Control-Allow-Origin" "*"
addHeader "Access-Control-Allow-Methods" "PUT, OPTIONS"
return $ RepPlain $ toContent ("" :: Text)
putMyRouteR :: Handler RepJson
putMyRouteR = do
addHeader "Access-Control-Allow-Origin" "*"
-- more stuff ...
This works, but it feels slightly un-Yesodic because it's so boilerplate. So, two questions:
- Do we have a better adjective than Yesodic?
- Is there another, better way to let a route support cross-origin requests?