Разрешить несколько заголовков с CORS в 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

основываясь на ответе на этот вопрос:Как установить ответ Json в 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.

Итак, как мне разрешить любое количество заголовки в запросе CORS в Suave?

редактировать

Попытка #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 to 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.

2 ответов


попробуйте использовать addHeader вместо setHeader. Всего несколько строк ниже в модульных тестах, которые вы нашли, есть тест для addHeader Это показывает, что у него есть семантика, которую вы ищете, и его документация говорит:

добавляет заголовок ключ с заданным значением в список возвращаемых заголовков, даже если заголовок уже существует. Это означает, что Suave будет служить ответом с заголовком, обозначенным key С, возможно, разными ценности.

это похоже на поведение, которое вы хотите.


У меня была похожая проблема. Из-за унаследованных причин я застрял на данный момент с verion 1.1.3, хотя Suave 2.2.1 доступен. Я не очень хорошо знаком с 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
                        // ...
                        ] )
    ]

Я уверен, что есть pretier пути.