2017-06-04 65 views
5

我試圖讓我的Suave API接受CORS請求。我已經按照這個片段在這裏:在Suave中允許使用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. 

也基於同樣的問題,我試了f ollowing:

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請求標頭的任何金額是多少?

編輯

嘗試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

嘗試使用addHeader而不是setHeader。短短几行進一步下跌中,你發現在單元測試中,有一個爲addHeader一個測試表明,它有你要找的語義,其文檔說:

與給定會將頭鍵值添加到返回的標題列表中,即使該標題已經存在。這意味着Suave將以key表示的標題作爲響應,並可能有不同的值。

這看起來像你想要的行爲。

+0

這使得完美的感覺和易於應用,所以很自然它仍然是破損:(請參閱我上面的編輯 – Max

+0

https://www.html5rocks.com/en/tutorials/cors/說'訪問控制-Allow-Methods'也是必需的;你是否在任何地方設置?如果不是,可能真正的問題是缺少Access-Control-Allow-Methods頭,錯誤信息是誤導性的。只是猜測在這一點上,我會說閱讀https://www.html5rocks.com/en/tutorials/cors/,並繼續嘗試不同的標題組合,直到你找到正確的CORS標頭集合對不起,我不能比這更有幫助 – rmunn

+0

這使我朝着正確的方向發展 - 事實證明,我可以使用整個'Suave.CORS'命名空間,這自然是我沒有找到,直到我通過這個問題。 – Max

1

我有類似的問題。由於遺留原因,即使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 
         // ... 
         ]) 
    ] 

我敢肯定有一個pretier方式。

相關問題