2016-11-21 79 views
1

我想加爲我的阿卡HTTP API CORS支持:https://github.com/lomigmegard/akka-http-corsCORS與headerValueByName問題(阿卡-HTTP-CORS)阿卡HTTP同時使用<code>akka-http-cors</code>

一切正常時,我基本上將CORS支持一個簡單路線,例如:

val route = cors() { 
    path("ping") { 
     get { 
      complete("pong") 
     } 
    } 
} 

與相應的jQuery的電話:

$.ajax({ 
    url: "http://localhost:9000/ping", 
    type: "GET", 
    success: function(data) { alert(data); } 
    }); 

返回正確「傍」預期


但是,當我嘗試提取(服務器端)從請求某些特定標題時,CORS支持的響應似乎是突然被打破。例如,有:

val route = cors() { 
    headerValueByName("myheader") { (myheader) => 
     path("ping") { 
      get { 
       complete("pong") 
      } 
     } 
    } 
} 

與相應的jQuery的電話:

$.ajax({ 
    url: "http://localhost:9000/ping", 
    type: "GET", 
    beforeSend: function(xhr){xhr.setRequestHeader('myheader', 'test');}, 
    success: function(data) { alert('Success!' + data); } 
    }); 

失敗,CORS錯誤控制檯:

XMLHttpRequest cannot load http://localhost:9000/ping. 
No 'Access-Control-Allow-Origin' header is present on the requested resource. 
Origin 'http://localhost:8080' is therefore not allowed access. 
The response had HTTP status code 400. 

看來,加入headerValueByName(...)到航路中斷cors支持,我不明白爲什麼。

我也嘗試過cors的不同實現(基於自定義特性),並且所有這些行爲都是相同的。

我在這裏錯過了什麼?

回答

1

請使用類似curl這樣的工具來調試您的服務器路由,以查看來自服務器的實際響應,而不是JavaScript的解釋。

curl -X GET -H "Origin: http://example.com" -H "myheader: test" http://localhost:9000/ping 

我懷疑你的自定義頭沒有在HTTP請求中正確發送。 headerValueByName指令將拒絕該請求。拒絕冒泡(跳過cors指令)最終由默認拒絕處理程序處理。 CORS相關的標題因此沒有響應。

你應該有你的拒絕和異常處理程序裏面cors指令,而不是外部(如默認的)。請看下面的例子。

def route: Route = { 
    import CorsDirectives._ 
    import Directives._ 

    // Your CORS settings 
    val corsSettings = CorsSettings.defaultSettings 

    // Your rejection handler 
    val rejectionHandler = corsRejectionHandler withFallback RejectionHandler.default 

    // Your exception handler 
    val exceptionHandler = ExceptionHandler { 
    ... 
    } 

    // Combining the two handlers only for convenience 
    val handleErrors = handleRejections(rejectionHandler) & handleExceptions(exceptionHandler) 

    // Note how rejections and exceptions are handled *before* the CORS directive (in the inner route). 
    // This is required to have the correct CORS headers in the response even when an error occurs. 
    handleErrors { 
    cors(corsSettings) { 
     handleErrors { 
     ... // your business route here 
     } 
    } 
    } 
} 

這不會解決你的頭的問題,但至少CORS標頭將是,即使該路由被拒絕或失敗,一個異常的HTTP響應的一部分。

+0

非常感謝!你完全正確:) – Elsener