Разрешение запросов перекрестного происхождения в Yesod

Мое приложение использует букмарклет, и мне нужно разрешить CORS для MyRouteR, поэтому мой код букмарклета может использовать этот маршрут для запросов AJAX.

В моем первом проекте config/routes я дал поддержку MyRouteR только для одного метода запроса PUT. Но оказалось (duh), что мне нужно будет также поддерживать метод OPTIONS, какие браузеры используют для предпродажных запросов CORS.

В конфигурации/маршрутах я получил следующее:

/myroute MyRouteR PUT OPTIONS

Я как бы надеялся, что в Template Haskell будет задействован соответствующий механизм, который обрабатывает конфигурацию/маршруты, чтобы добавление OPTIONS в этот список методов маршрута автоматически приводило к поддержке CORS, но не к кости. Не конец света, но это имело бы смысл и чувствовал себя таким элегантным.

Чтобы сделать работу CORS, я дал маршрут обработчику OPTIONS:

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

Это работает, но он чувствует себя немного не-йесодическим, потому что он так тщательно. Итак, два вопроса:

  • Есть ли у нас лучшее прилагательное, чем есодическое?
  • Есть ли другой, лучший способ разрешить маршрутизацию запросов кросс-происхождения?

Ответы

Ответ 1

UPDATE: Кто-то еще опубликовал какое-то общее промежуточное ПО для этого: http://hackage.haskell.org/package/wai-cors.


В настоящее время я работаю над одним и тем же и еще не реализовал решение, однако, я думаю, это можно сделать с помощью WAI Middleware, аналогичного образцу кода на странице wiki Разрешить доступ к шрифтам WOFF из других доменов (CORS). Это должно позволить вам писать код CORS один раз, не повторяя себя.

Пример кода из приведенной выше ссылки, чтобы добавить доступ к перекрестному доступу для шрифтов WOFF:

addCORStoWOFF :: W.Middleware
addCORStoWOFF app = fmap updateHeaders . app
  where
    updateHeaders (W.ResponseFile    status headers fp mpart) = W.ResponseFile    status (new headers) fp mpart
    updateHeaders (W.ResponseBuilder status headers builder)  = W.ResponseBuilder status (new headers) builder
    updateHeaders (W.ResponseSource  status headers src)      = W.ResponseSource  status (new headers) src
    new headers | woff      = cors : headers
                | otherwise =        headers
      where woff = lookup HT.hContentType headers == Just "application/font-woff"
            cors = ("Access-Control-Allow-Origin", "*")