【问题标题】:CORS response headers not working in Spray when requested from browser从浏览器请求时,CORS 响应标头在 Spray 中不起作用
【发布时间】:2014-06-17 06:53:57
【问题描述】:

我试图在 Spray 服务器上实现 CORS 支持(版本 1.1-20131011,其中已经支持 cors 标头)。

目前,服务器代码如下所示:

trait DefaultCORSDirectives { this: Directives =>
  def defaultCORSHeaders = respondWithHeaders(
      `Access-Control-Allow-Origin`(AllOrigins),
      `Access-Control-Allow-Methods`(HttpMethods.GET, HttpMethods.POST, HttpMethods.OPTIONS, HttpMethods.DELETE,
      HttpMethods.CONNECT, HttpMethods.DELETE, HttpMethods.HEAD, HttpMethods.PATCH, HttpMethods.PUT, HttpMethods.TRACE),
      `Access-Control-Allow-Headers`("Origin, X-Requested-With, Content-Type, Accept, Accept-Encoding, Accept-Language, Host," +
    " Referer, User-Agent, Overwrite, Destination, Depth, X-Token, X-File-Size, If-Modified-Since, X-File-Name, Cache-Control"),
      `Access-Control-Allow-Credentials`(true),
      `Access-Control-Max-Age`(3600)
    )
}

并且是这样使用的

  defaultCORSHeaders {
      options {
        complete {
          StatusCodes.OK
        }
      } ~
      post {
        path("path") {
          //response
      }
   }

使用 curl 时,POST 和 OPTIONS 方法的响应均符合预期。但是从浏览器中,我得到 Origin is not allowed by Access-Control-Allow-Origin (Chrome) 或 Error 415 Unsupported Media Type (Firefox) 并且似乎根本没有发送 POST 请求。

请求jQuery代码如下:

$(document).ready(function () {
        $.post(url,
            {
               'params': "params",
            },
            function (data) {
                //handle response
            }
    );
});

我已阅读 CORS 规范和我能找到的所有资源,尝试了 Access-Control-Allow- 标头的任何可能组合(有和没有 Access-Control-Allow-Credentials,Access-Control-Allow 的不同内容-Headers 和 Access-Control-Allow-Methods,Access-Control-Allow-Origin 设置为 * 或单个 Origin 等)。我还尝试从磁盘(Origin null)、网络服务器(Origin localhost:8888)和远程服务器(Origin 标准 url)运行脚本,因为某些浏览器显然会阻止来自本地的请求,但总是相同的负面结果。

任何帮助如何使它工作将不胜感激。

【问题讨论】:

    标签: jquery scala cors spray http-options-method


    【解决方案1】:

    声明一个新指令:

    trait CORSSupport extends Directives {
       private val CORSHeaders = List(
         `Access-Control-Allow-Methods`(GET, POST, PUT, DELETE, OPTIONS),
         `Access-Control-Allow-Headers`("Origin, X-Requested-With, Content-Type, Accept, Accept-Encoding, Accept-Language, Host, Referer, User-Agent"),
         `Access-Control-Allow-Credentials`(true)
       )
    
       def respondWithCORS(origin: String)(routes: => Route) = {
         val originHeader = `Access-Control-Allow-Origin`(SomeOrigins(Seq(HttpOrigin(origin))))
         respondWithHeaders(originHeader :: CORSHeaders) {
           routes ~ options { complete(StatusCodes.OK) }
         }
       }
     }
    

    使用新指令:

    trait Api extends Directives with RouteConcatenation with CORSSupport with ConfigHolder{
        this: CoreActors with Core => 
    
        val routes =
          respondWithCORS(config.getString("origin.domain")) {
    
            pathPrefix("api") { 
              new DemoRoute().route
            } 
          }
    
        val rootService = system.actorOf(ApiService.props(config.getString("hostname"), config.getInt("port"), routes))
      }
    

    https://github.com/wesovilabs/spray-cors-demo/blob/master/README.md

    【讨论】:

      【解决方案2】:

      我没有使用指令,但我尝试了 rawheader 并且它有效。

      代码如下:

       path("ping"){
         get{
           respondWithMediaType(`application/json`){
             respondWithHeader(RawHeader("Access-Control-Allow-Origin","*")){
               complete{
                 jsonPrefix + """{"result": "PONG"}"""
               }
             }
           }
         }
       }
      

      【讨论】:

        【解决方案3】:

        如果您的 API 中有授权,则必须在 Access-Control-Allow-Headers 中包含 Authorization 标头。

        从 cUrl 测试 cors 的唯一方法是使用 Origin 标头:curl cors

        【讨论】:

          猜你喜欢
          • 2012-02-06
          • 2023-01-26
          • 2021-11-01
          • 2021-12-13
          • 1970-01-01
          • 2017-08-13
          • 2021-03-19
          • 2018-06-04
          • 2015-12-05
          相关资源
          最近更新 更多