I have a Play 2.0.1 application that I want to call using Javascript hosted on other domains. My Javascript call is failing with:
Origin http://mydomain.com is not allowed by Access-Control-Allow-Origin.
I have found a number of examples of how to set the correct HTTP header in Play 1, but have not found anything for Play 2.0.1. After reading the documentation (http://www.playframework.org/documentation/2.0.2/JavaResponse) I've tried the following just to get things working:
public static Result myJsonWebService() {
...
response().setHeader("Access-Control-Allow-Origin", "*");
return ok(toJson(jsonObject));
}
but my JS web service call is still failing.
What do I need to do to get this working?
Limiting the possible Access-Control-Allow-Origin values to a set of allowed origins requires code on the server side to check the value of the Origin request header, compare that to a list of allowed origins, and then if the Origin value is in the list, set the Access-Control-Allow-Origin value to the same value as ...
What is the Access-Control-Allow-Origin response header? The Access-Control-Allow-Origin header is included in the response from one website to a request originating from another website, and identifies the permitted origin of the request.
You can just put the Header set Access-Control-Allow-Origin * setting in the Apache configuration or htaccess file. It should be noted that this effectively disables CORS protection, which very likely exposes your users to attack.
Access-Control-Allow-Origin specifies either a single origin which tells browsers to allow that origin to access the resource; or else — for requests without credentials — the " * " wildcard tells browsers to allow any origin to access the resource.
Just for Scala guys, this is the implementation I'm currently using:
import play.api.mvc._
import scala.concurrent._
import play.api.http.HeaderNames._
/**
* Action decorator that provide CORS support
*
* @author Giovanni Costagliola, Nick McCready
*/
case class WithCors(httpVerbs: String*)(action: EssentialAction) extends EssentialAction with Results {
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") { // preflight
val corsAction = Action {
request =>
Ok("").withHeaders(
ACCESS_CONTROL_ALLOW_ORIGIN -> origin,
ACCESS_CONTROL_ALLOW_METHODS -> (httpVerbs.toSet + "OPTIONS").mkString(", "),
ACCESS_CONTROL_MAX_AGE -> "3600",
ACCESS_CONTROL_ALLOW_HEADERS -> s"$ORIGIN, X-Requested-With, $CONTENT_TYPE, $ACCEPT, $AUTHORIZATION, X-Auth-Token",
ACCESS_CONTROL_ALLOW_CREDENTIALS -> "true")
}
corsAction(request)
} else { // actual request
action(request).map(res => res.withHeaders(
ACCESS_CONTROL_ALLOW_ORIGIN -> origin,
ACCESS_CONTROL_ALLOW_CREDENTIALS -> "true"
))
}
}
}
To use it just decorate your action in the following way:
def myAction = WithCors("GET", "POST") {
Action { request =>
???
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With