rOrlig
rOrlig

Reputation: 2529

Allowing Cross Origin Domain Sharing

I wanted to check how to enable Cross Origin Domain Sharing in Playframework 2.1 (Java). I didn't see any documentation on how to do this.

Upvotes: 3

Views: 1851

Answers (2)

pangiole
pangiole

Reputation: 991

Using the Scala language, a nice and simple PlayFramework solution could be using the following ActionBuilder

import play.api.mvc._
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global

// An Actionbuilder for CORS - Cross Origin Resource Sharing  
object CorsAction extends ActionBuilder[Request] {

  def invokeBlock[A](request: Request[A], block: (Request[A]) ⇒ Future[SimpleResult]): Future[SimpleResult] = {
    block(request).map { result =>
      request.headers.get("Origin") match {
        case Some(o) => result.withHeaders("Access-Control-Allow-Origin" -> o)
        case None => result
      }
    }
  }
}

The ActionBuilder overrides the invokeBlock method with the purpose to map the result created by your application controller action (wrapped by a Future object in Play >= 2.1) into the same result having the additional "Access-Control-Allow-Origin" header field if the request came with the "Origin" header field.

The above action builder can be used simply as follows:

object MyController extends Controller {

  def myAction = CorsAction {
     Ok("whatever HTML or JSON you want")
     // it will be certainly processed by your browser
  }
}

Upvotes: 2

palako
palako

Reputation: 3480

Not sure how this translates to 2.x, but in 1.2.5 what I do is this. The Access-Control-Allow-Headers is optional if you have non standard headers. You can change the * of the Allow-Origin to only match the domains you want to allow.

@Before
static void CORS() {
    if(request.headers.containsKey("origin")){
        response.headers.put("Access-Control-Allow-Origin", new Header("Access-Control-Allow-Origin", "*"));
        response.headers.put("Access-Control-Allow-Headers", new Header("Access-Control-Allow-Headers", "my-custom-header, my-second-custom-header"));
    }
}

If you have non standard methods (GET/POST) or use custom headers, most user agents are going to have a preflight OPTIONS call, so you what I do is add this to my routes file:

#This catches the preflight CORS calls
OPTIONS /{path}                                 Application.options

and this in my controller:

/**
 * Cross Origin Request Sharing calls are going to have a pre-flight option call because we use the "non simple headers"
 * This method catches those, (headers handling is done in the CORS() method)
 */
public static void options() {}

Upvotes: 2

Related Questions