Play Framework 2.3 - CORS标题

Ser*_*iel 6 java playframework

更新新的Play 2.5提供了一个新的CORS过滤器

随着新的2.3 Java版本完成将Response类迁移到Promise类,以下代码不再有效.

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); 
 } 
}
Run Code Online (Sandbox Code Playgroud)

我正在开发Play(Java)2.3中的应用程序,我已经查看并尝试了不同的方法来启用CORS - 包括向路由文件添加/ OPTIONS方法 - 但没有成功.

我非常感谢新的Response实现如何处理这种类型的拦截,因为在新的Promise类中实现时,它似乎没有对头文件产生任何影响.

在此先感谢所有的帮助!!

cyb*_*bis 8

解决了这个问题:

来自服务器的所有API响应都应包含标题:"Access-Control-Allow-Origin","*".我们需要为所有动作响应编写一个包装器.

在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));
  }

}
Run Code Online (Sandbox Code Playgroud)

POST,PUT等服务器请求在主请求之前向服务器发出预检请求.这些预检请求的响应应包含以下标题:

"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"

在路线中添加:

OPTIONS /*all                           controllers.Application.preflight(all)
Run Code Online (Sandbox Code Playgroud)

在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();
    }

}
Run Code Online (Sandbox Code Playgroud)

PS:通过这种方法,我不必为此创建一个scala过滤器.


小智 2

看起来您可能已经解决了您的问题,但为了清楚起见......

你已经非常接近了......我相信你不需要实例化你自己的 Response 对象,你可以只调用通过方法传入的对象:

public Result call() throws Throwable
{     
    response().setHeader("Access-Control-Allow-Origin", "*"); 
       //Handle preflight requests 
    if(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();
    } 
    else
    {
          return badRequest();
    }
}
Run Code Online (Sandbox Code Playgroud)

希望有帮助。