Composing with Play's EssentialAction

流过昼夜 提交于 2019-12-09 22:58:52

问题


I'm using Play 2.2.1 and I'm trying to write my own Action to deal with CORS requests. I found this but unfortunately it doesn't compile.

Just for reference here's the (slightly modified) code:

import play.api.mvc._
import scala.concurrent.ExecutionContext

case class CorsAction(action: EssentialAction) extends EssentialAction {
  def apply(request: RequestHeader) = {
    implicit val executionContext: ExecutionContext = play.api.libs.concurrent.Execution.defaultContext
    val origin = request.headers.get("Origin").getOrElse("*")

    if (request.method == "OPTIONS") {
      val cors = Action { request =>
        Ok("").withHeaders(
          "Access-Control-Allow-Origin" -> origin,
          "Access-Control-Allow-Methods" -> "GET, POST, PUT, DELETE, OPTIONS",
          "Access-Control-Allow-Headers" -> "Accept, Origin, Content-type, Authorization, X-Auth-Token, " +
            "X-HTTP-Method-Override, X-Json, X-Prototype-Version, X-Requested-With",
          "Access-Control-Allow-Credentials" -> "true",
          "Access-Control-Max-Age" -> (60 * 60 * 24 * 30).toString)
      }

      cors(request)
    } else {
        action(request).map(res =>
          res.withHeaders(
            "Access-Control-Allow-Origin" -> origin,
            "Access-Control-Allow-Credentials" -> "true"
      ))
    }
  }
}

The error is:

Cors.scala:13: not found: value Ok

I'm very new to Scala and even more so to Play! and can't figure out what's going on. As far as I know I have to use EssentialAction and not just Action b/c I want to get to the header of the request. All the examples I found so far involve only Action.


回答1:


As Will said you are missing the the Results trait.

A probably cleaner way to implement the CorsAction would be to use ActionBuildersas described in http://www.playframework.com/documentation/2.2.x/ScalaActionsComposition

The implementation would look like this:

import play.api.mvc._
import scala.concurrent.{ExecutionContext, Future}

object CorsAction extends ActionBuilder[Request] with Results{
  val MaxAge = 60 * 60 * 24 * 30

  val AllowHeaders = List(
    "Accept", "Origin", "Content-type", "Authorization", "X-Auth-Token",
    "X-HTTP-Method-Override", "X-Json", "X-Prototype-Version", "X-Requested-With")

  val AllowMethods = List("GET", "POST", "PUT", "DELETE", "OPTIONS")

  val AllowCredentials = true

  def cors[A](origin: String) =
    Ok.withHeaders(
      "Access-Control-Allow-Origin" -> origin,
      "Access-Control-Allow-Methods" -> AllowMethods.mkString(", "),
      "Access-Control-Allow-Headers" -> AllowHeaders.mkString(", "),
      "Access-Control-Allow-Credentials" -> AllowCredentials.toString,
      "Access-Control-Max-Age" -> MaxAge.toString)

  def invokeBlock[A](request: Request[A], block: (Request[A]) => Future[SimpleResult]) = {
    implicit val executionContext = play.api.libs.concurrent.Execution.defaultContext
    val origin = request.headers.get("Origin").getOrElse("*")

    if (request.method == "OPTIONS") {
      Future.successful(cors(origin))
    } else {
      block(request).map(res =>
        res.withHeaders(
          "Access-Control-Allow-Origin" -> origin,
          "Access-Control-Allow-Credentials" -> AllowCredentials.toString
        ))
    }
  }
}



回答2:


You need to import the Results trait -- the Ok val is defined there.

http://www.playframework.com/documentation/2.2.x/api/scala/index.html#play.api.mvc.Results



来源:https://stackoverflow.com/questions/20530273/composing-with-plays-essentialaction

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!