UPDATE the new Play 2.5 offers a new CORS Filter
As the new 2.3 Java version finished the migration of the Response class to Promise class the following code no longer works.
public class CorsAction extends Action.Simple {
public Result call(Context context) throws Throwable{
Response response = context.response();
response.setHeader("Access-Control-Allow-Origin", "*");
//Handle preflight requests
if(context.request().method().equals("OPTIONS")) {
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content- Type, Accept, Authorization, X-Auth-Token");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Origin", "*");
return ok()
}
response.setHeader("Access-Control-Allow-Headers","X-Requested-With, Content-Type, X- Auth-Token");
return delegate.call(context);
}
}
I am developing an application in Play (Java) 2.3 and I have looked and tried different methods to enable CORS -including adding /OPTIONS methods to the routes file- without success.
I would much appreciate some light on how the new Response implementation would handle this type of interception, because it seems not to have any effects in the headers when implemented in the new Promise class.
Thanks in advance for all the help!!
Solved this by:
All API responses from the server should contain a header: “Access-Control-Allow-Origin”, “*”. We need to write a wrapper for all action responses.
In Global.java
import java.net.URL;
import play.*;
import play.libs.F.Promise;
import play.mvc.Action;
import play.mvc.Http;
import play.mvc.Result;
public class Global extends GlobalSettings {
// For CORS
private class ActionWrapper extends Action.Simple {
public ActionWrapper(Action<?> action) {
this.delegate = action;
}
@Override
public Promise<Result> call(Http.Context ctx) throws java.lang.Throwable {
Promise<Result> result = this.delegate.call(ctx);
Http.Response response = ctx.response();
response.setHeader("Access-Control-Allow-Origin", "*");
return result;
}
}
@Override
public Action<?> onRequest(Http.Request request,
java.lang.reflect.Method actionMethod) {
return new ActionWrapper(super.onRequest(request, actionMethod));
}
}
Server requests like POST, PUT make a preflight request to the server before the main request. The response for these preflight requests should contain below headers:
“Access-Control-Allow-Origin”, “” “Allow”, “” “Access-Control-Allow-Methods”, “POST, GET, PUT, DELETE, OPTIONS” “Access-Control-Allow-Headers”, “Origin, X-Requested-With, Content-Type, Accept, Referer, User-Agent”
In routes add:
OPTIONS /*all controllers.Application.preflight(all)
In Application Coltroller:
package controllers;
import play.mvc.*;
public class Application extends Controller {
public static Result preflight(String all) {
response().setHeader("Access-Control-Allow-Origin", "*");
response().setHeader("Allow", "*");
response().setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, DELETE, OPTIONS");
response().setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Referer, User-Agent");
return ok();
}
}
PS: By this approach I did not have to create a scala filter for this.
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