【问题标题】:cors in akka http with headerValueByName issue (akka-http-cors)带有 headerValueByName 问题的 akka http 中的 cors (akka-http-cors)
【发布时间】:2016-12-14 05:29:42
【问题描述】:

我正在尝试在使用 akka-http-cors 时为我的 akka http API 添加 CORS 支持:https://github.com/lomigmegard/akka-http-cors

当我基本上将 cors 支持添加到 simple 路线时,一切正常,例如:

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

使用相应的 jQuery 调用:

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

按预期正确返回“pong”


但是当我尝试从请求中提取(服务器端)某些特定标头时,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 的不同实现(基于自定义特征),并且它们的行为都是相同的。

我在这里错过了什么?

【问题讨论】:

    标签: scala cors akka akka-http


    【解决方案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 响应的一部分,即使路由被拒绝或因异常而失败。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-12
      • 2018-07-08
      • 2019-11-03
      • 2016-11-30
      • 1970-01-01
      相关资源
      最近更新 更多