Haskell Yesod - 浏览器的CORS问题OPTIONS在执行POST请求时的请求

时间:2016-12-30 15:58:42

标签: rest haskell request cors yesod

我使用了Network.Wai.Middleware.Cors的{​​{1}},它适用于simpleCors次请求,但当我尝试发出GET请求时,我遇到了以下问题

POST

我能够使其发挥作用的唯一方法是从OPTIONS /users Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Status: 400 Bad Request 0.032443s

中的以下部分删除simpleCors
Application.hs

并添加OPTIONS方法响应

-- | Convert our foundation to a WAI Application by calling @toWaiAppPlain@ and
-- applying some additional middlewares.
makeApplication :: App -> IO Application
makeApplication foundation = do
    logWare <- makeLogWare foundation
    -- Create the WAI application and apply middlewares
    appPlain <- toWaiAppPlain foundation
    return $ logWare $ defaultMiddlewaresNoLogging $ simpleCors $ appPlain

并添加CORS头...但它是一个肮脏的解决方案,因为我需要更改所有我的API处理程序!任何帮助都非常感谢!

2 个答案:

答案 0 :(得分:3)

我认为问题在于simpleCorssimpleCorsResourcePolicy构建的,仅涵盖simpleMethods,但不包括AsyncTask

您可以使用相同的方法来解决此问题,以推送您需要的任何中间件。

这是我用于您所描述的OPTIONS问题的那个:

OPTIONS

然后只需编写您需要的中间件,就像您已经在做的那样:

{-# LANGUAGE OverloadedStrings #-}

module Middlewares where

import Network.Wai                       (Middleware)
import Network.Wai.Middleware.AddHeaders (addHeaders)
import Network.Wai.Middleware.Cors       (CorsResourcePolicy(..), cors)

-- | @x-csrf-token@ allowance.
-- The following header will be set: @Access-Control-Allow-Headers: x-csrf-token@.
allowCsrf :: Middleware
allowCsrf = addHeaders [("Access-Control-Allow-Headers", "x-csrf-token,authorization")]

-- | CORS middleware configured with 'appCorsResourcePolicy'.
corsified :: Middleware
corsified = cors (const $ Just appCorsResourcePolicy)

-- | Cors resource policy to be used with 'corsified' middleware.
--
-- This policy will set the following:
--
-- * RequestHeaders: @Content-Type@
-- * MethodsAllowed: @OPTIONS, GET, PUT, POST@
appCorsResourcePolicy :: CorsResourcePolicy
appCorsResourcePolicy = CorsResourcePolicy {
    corsOrigins        = Nothing
  , corsMethods        = ["OPTIONS", "GET", "PUT", "POST"]
  , corsRequestHeaders = ["Authorization", "Content-Type"]
  , corsExposedHeaders = Nothing
  , corsMaxAge         = Nothing
  , corsVaryOrigin     = False
  , corsRequireOrigin  = False
  , corsIgnoreFailures = False
}

答案 1 :(得分:0)

简化Mario的答案,我们可以使用simplePolicy

import Network.Wai.Middleware.Cors 

allowCors :: Middleware
allowCors = cors (const $ Just appCorsResourcePolicy)

appCorsResourcePolicy :: CorsResourcePolicy
appCorsResourcePolicy =
    simpleCorsResourcePolicy
        { corsMethods = ["OPTIONS", "GET", "PUT", "POST"]
        , corsRequestHeaders = ["Authorization", "Content-Type"]
        }

并使用它:

main = scotty 8080 $ do
    middleware allowCors
    matchAny  "/" $ text "Success"