6

我正在尝试让我的 Suave API 接受 CORS 请求。我在这里遵循了这个片段:

http://www.fssnip.net/mL/title/CORS-response-with-Suave

我将在这里重新创建:

let setCORSHeaders =
    setHeader  "Access-Control-Allow-Origin" "*"
    >=> setHeader "Access-Control-Allow-Headers" "content-type"

let allow_cors : WebPart =
    choose [
        OPTIONS >=>
            fun context ->
                context |> (
                    setCORSHeaders
                    >=> OK "CORS approved" )
    ]

let webSite =
    choose [
        allow_cors
        GET >=> OK "URLs are for wimps. GETting something? This is what you get."
    ]

但是现在我有需要传入令牌的端点,并且由于缺少 CORS 中允许的标头,这些端点正在给出错误。我的令牌头只是“令牌”,所以我尝试了两件事,但都没有解决问题。

尝试#1

    setHeader  "Access-Control-Allow-Origin" "*"
    >=> setHeader "Access-Control-Allow-Headers" "content-type"
    >=> setHeader "Access-Control-Allow-Headers" "token"

这返回了一个错误,说content-type不再接受 - 这似乎意味着最后一个setHeader覆盖了第一个,当您在此处查看源代码时:https ://github.com/SuaveIO/suave/blob/master/src/Suave .Tests/HttpWriters.fs在第 113 行,有一个测试对我来说意味着这是所需的行为。

尝试#2

根据对这个问题的回答:How to set a Json response in suave webpart,我尝试通过逗号分隔的列表设置两个标题:

    setHeader  "Access-Control-Allow-Origin" "*"
    >=> setHeader "Access-Control-Allow-Headers" "Content-Type,token"

但这随后给出了一个错误,表明 CORS 完全失败了:

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. The response had HTTP status code 401.

同样基于同样的问题,我尝试了以下方法:

    setHeader  "Access-Control-Allow-Origin" "*"
    >=> setHeader "Access-Control-Allow-Headers:content-type" "Accept"
    >=> setHeader "Access-Control-Allow-Headers:token" "Accept"

这给出了这样的回应:Request header field token is not allowed by Access-Control-Allow-Headers in preflight response.

那么,如何在 Suave 的 CORS 请求中允许任意数量的标头?

编辑

尝试#3

我用addHeader而不是setHeader

let setCORSHeaders =
    setHeader  "Access-Control-Allow-Origin" "*"
    >=> addHeader "Access-Control-Allow-Headers" "content-type"
    >=> addHeader "Access-Control-Allow-Headers" "token"

现在是说...No 'Access-Control-Allow-Origin' header is present on the requested resource.

如果我先将其更改setHeaderaddHeader,我仍然会得到相同的响应。

使固定

    addHeader  "Access-Control-Allow-Origin" "*" 
    >=> setHeader "Access-Control-Allow-Headers" "token" 
    >=> addHeader "Access-Control-Allow-Headers" "content-type" 
    >=> addHeader "Access-Control-Allow-Methods" "GET,POST,PUT" 

完成了这项工作 - 在此之后,发送的内容出现了问题,但 CORS 本身就没有其他问题了。

4

2 回答 2

5

尝试使用addHeader而不是setHeader. 在您找到的单元测试中再往下几行,有一个测试addHeader表明它具有您正在寻找的语义,并且它的文档说:

将具有给定值的标题键添加到返回的标题列表中,即使该标题已经存在。这意味着 Suave 将提供一个响应,其标头由key可能不同的值表示。

这看起来像您想要的行为。

于 2017-06-05T00:34:57.137 回答
2

我有一个类似的问题。由于遗留原因,即使 Suave 2.2.1 可用,我目前仍坚持使用 1.1.3 版。我对 F# 不是很熟悉,但最终我设法通过这样的方式来解决这个问题:

let setCORSHeaders =
    addHeader  "Access-Control-Allow-Origin" "*" 
    >=> setHeader "Access-Control-Allow-Headers" "token" 
    >=> addHeader "Access-Control-Allow-Headers" "content-type" 
    >=> addHeader "Access-Control-Allow-Methods" "GET,POST,PUT" 

let app =
    choose [
        GET >=>
            fun context ->
                context |> (
                    setCORSHeaders
                    >=> choose
                        [ pathRegex "(.*?)\.(dll|mdb|log)$" >=> dllFilesRequest
                        pathRegex "(.*?)\.(html|css|js|png|jpg|ico|bmp)$" >=> staticFilesRequest

                        path "/" >=> indexRequest
                        path "/index" >=> indexRequest
                        path "/static" >=> staticFilesRequest
                        // ...
                        ] )

        POST >=>
            fun context ->
                context |> (
                    setCORSHeaders
                    >=> choose
                        [
                        path "/something" >=> runSomething
                        // ...
                        ] )
    ]

我敢肯定有一个更漂亮的方法。

于 2017-08-23T11:17:39.200 回答