我正在尝试让我的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.
如果我先将setHeader
更改为addHeader
,我仍会得到相同的回复。
修正
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本身也没有问题。
答案 0 :(得分:5)
尝试使用addHeader
代替setHeader
。在您找到的单元测试中,只有几行,addHeader
的测试表明它具有您正在寻找的语义,并且其文档说明:
将具有给定值的标头密钥添加到返回标头列表中,即使该标头已存在。这意味着Suave将使用
key
表示的标题提供响应,其值可能不同。
这看起来像你想要的行为。
答案 1 :(得分:1)
我有类似的问题。由于遗留的原因,即使Suave 2.2.1可用,我仍然坚持使用Verion 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
// ...
] )
]
我确定有一种更好的方式。