java Play Framework 2.3 - CORS 标头
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25152277/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Play Framework 2.3 - CORS Headers
提问by Sergio Daniel
UPDATEthe new Play 2.5 offers a new CORS Filter
更新新的 Play 2.5 提供了一个新的CORS 过滤器
As the new 2.3 Java version finished the migration of the Response class to Promise class the following code no longer works.
由于新的 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);
}
}
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.
我正在 Play (Java) 2.3 中开发一个应用程序,我查看并尝试了不同的方法来启用 CORS - 包括向路由文件添加 /OPTIONS 方法 - 但没有成功。
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.
我非常感谢新的 Response 实现将如何处理这种类型的拦截,因为在新的 Promise 类中实现时,它似乎对标头没有任何影响。
Thanks in advance for all the help!!
在此先感谢您的帮助!!
回答by cyberabis
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.
来自服务器的所有 API 响应都应包含一个标头:“Access-Control-Allow-Origin”、“*”。我们需要为所有动作响应编写一个包装器。
In Global.java
在 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:
像 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”
“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.
PS:通过这种方法,我不必为此创建 scala 过滤器。
回答by CaptainKerk
It looks like you may have solved your problem, but just for clarity...
看起来您可能已经解决了您的问题,但只是为了清楚起见......
You are pretty close...I believe you don't need to instantiate your own Response object, you can just call the one passed in via a method:
你很接近......我相信你不需要实例化你自己的 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();
}
}
Hope that helps.
希望有帮助。
回答by Tinus
Cross post from enable-cors-in-java-play-framework-2-2-x.
从enable-cors-in-java-play-framework-2-2-x交叉发布。
The solutions proposed by @alexhanschke does not work when the request throws an exception (internal server error), because filters are not applied when that happens (see https://github.com/playframework/playframework/issues/2429). To solve that you have to wrap a scala class and return that as a result, as shown below in full. Please note that this still requires the options route specified and a controller to handle the options request.
@alexhanschke 提出的解决方案在请求引发异常(内部服务器错误)时不起作用,因为在发生这种情况时不会应用过滤器(请参阅https://github.com/playframework/playframework/issues/2429)。要解决这个问题,您必须包装一个 Scala 类并作为结果返回,如下所示。请注意,这仍然需要指定选项路由和控制器来处理选项请求。
See the entire thing here https://gist.github.com/tinusn/38c4c110f7cd1e1ec63f.
在此处查看整个内容https://gist.github.com/tinusn/38c4c110f7cd1e1ec63f。
import static play.core.j.JavaResults.BadRequest;
import static play.core.j.JavaResults.InternalServerError;
import static play.core.j.JavaResults.NotFound;
import java.util.ArrayList;
import java.util.List;
import play.GlobalSettings;
import play.api.mvc.Results.Status;
import play.libs.F.Promise;
import play.libs.Scala;
import play.mvc.Action;
import play.mvc.Http;
import play.mvc.Result;
import scala.Tuple2;
import scala.collection.Seq;
public class Global extends GlobalSettings {
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;
}
}
/*
* Adds the required CORS header "Access-Control-Allow-Origin" to successfull requests
*/
@Override
public Action<?> onRequest(Http.Request request, java.lang.reflect.Method actionMethod) {
return new ActionWrapper(super.onRequest(request, actionMethod));
}
private static class CORSResult implements Result {
final private play.api.mvc.Result wrappedResult;
public CORSResult(Status status) {
List<Tuple2<String, String>> list = new ArrayList<Tuple2<String, String>>();
Tuple2<String, String> t = new Tuple2<String, String>("Access-Control-Allow-Origin","*");
list.add(t);
Seq<Tuple2<String, String>> seq = Scala.toSeq(list);
wrappedResult = status.withHeaders(seq);
}
public play.api.mvc.Result toScala() {
return this.wrappedResult;
}
}
/*
* Adds the required CORS header "Access-Control-Allow-Origin" to bad requests
*/
@Override
public Promise<Result> onBadRequest(Http.RequestHeader request, String error) {
return Promise.<Result>pure(new CORSResult(BadRequest()));
}
/*
* Adds the required CORS header "Access-Control-Allow-Origin" to requests that causes an exception
*/
@Override
public Promise<Result> onError(Http.RequestHeader request, Throwable t) {
return Promise.<Result>pure(new CORSResult(InternalServerError()));
}
/*
* Adds the required CORS header "Access-Control-Allow-Origin" when a route was not found
*/
@Override
public Promise<Result> onHandlerNotFound(Http.RequestHeader request) {
return Promise.<Result>pure(new CORSResult(NotFound()));
}
}
回答by Phillip Kigenyi
This worked for me. However you may need to tweak some parameters(application.conf)
这对我有用。但是你可能需要调整一些参数(application.conf)
Step 1Create filters class(UrlFilter)
步骤 1创建过滤器类(UrlFilter)
package filters;
import play.mvc.EssentialFilter;
import play.filters.cors.CORSFilter;
import play.http.DefaultHttpFilters;
import javax.inject.Inject;
public class UrlFilter extends DefaultHttpFilters {
@Inject public UrlFilter(CORSFilter corsFilter) {
super(corsFilter);
}
}
Step 2import filters package in build.sbt
步骤 2在build.sbt 中导入过滤器包
libraryDependencies += filters
Step 3Register the UrlFilter class in application.conf
步骤 3在application.conf 中注册 UrlFilter 类
play.http.filters = "filters.UrlFilter"
NOTE: Remember to point to its exact location. Mine was in app/filters/UrlFilter.java
注意:请记住指向其确切位置。我的是在 app/filters/UrlFilter.java
Step 4Add the actual configurations that allow "access control allow origin" and many more. To the application.conf
步骤 4添加允许“访问控制允许来源”等的实际配置。到application.conf
play.filters.cors {
# The path prefixes to filter.
pathPrefixes = ["/"]
# The allowed origins. If null, all origins are allowed.
allowedOrigins = null
# The allowed HTTP methods. If null, all methods are allowed
allowedHttpMethods = null
# The allowed HTTP headers. If null, all headers are allowed.
allowedHttpHeaders = null
# The exposed headers
exposedHeaders = []
# Whether to support credentials
supportsCredentials = true
# The maximum amount of time the CORS meta data should be cached by the client
preflightMaxAge = 1 hour
}
Credithttps://www.playframework.com/documentation/2.5.x/CorsFilter
信用https://www.playframework.com/documentation/2.5.x/CorsFilter
https://www.playframework.com/documentation/2.5.x/resources/confs/filters-helpers/reference.conf
https://www.playframework.com/documentation/2.5.x/resources/confs/filters-helpers/reference.conf
回答by cyril
for me configuration working in chrome, firefox and explorer :
对我来说,在 chrome、firefox 和 explorer 中工作的配置: