玩 CORS 不工作
Play CORS not working
我已经在本地部署了我的 Play 应用程序,并且在我的浏览器中通过 localhost:9000
访问我的 REST API 完美无缺。
但是,从 file:///C:/Users/XXX/XXX//index.html
执行 jQuery 脚本(见下文)时出现以下错误:
Failed to load resource: the server responded with a status of 403 (Forbidden)
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. The response had HTTP status code 403.
我按照 https://www.playframework.com/documentation/2.6.x/CorsFilter 下给出的说明进行操作。
我的build.sbt
:
libraryDependencies ++= Seq(
jdbc,
evolutions,
guice,
"com.h2database" % "h2" % "1.4.194",
javaJpa,
"org.hibernate" % "hibernate-core" % "5.2.5.Final",
filters
)
我的application.conf
:
play.filters.enabled += "play.filters.cors.CORSFilter"
play.filters.cors {
# allow all paths
pathPrefixes = ["/"]
# allow all origins (You can specify if you want)
allowedOrigins = null
allowedHttpMethods = ["GET", "POST", "PUT", "DELETE"]
# allow all headers
allowedHttpHeaders = null
}
注意:我尝试了 allowedOrigins = null
和 allowedOrigins = ["*"]
jQuery-脚本:
$.ajax({
'url' : 'http://localhost:9000/employee/' + user_id + '/weeklyWorkingHours',
'type' : 'GET',
'success' : function(data) {
console.log('Data: '+ JSON.stringify(data));
},
'error' : function(request,error)
{
console.log("Error: "+JSON.stringify(request));
}
});
Play 是这样说的:
[warn] p.f.c.CORSFilter - Invalid CORS request;Origin=Some(null);Method=GET;Access-Control-Request-Headers=None
尝试将其放入 application.conf(它将允许所有来源)
play.filters.cors.allowedOrigins = null
并且不要禁用 cors 过滤器
play.filters.enabled += "play.filters.cors.CORSFilter"
您将无法从本地文件中获取 CORS。浏览器向服务器发送一个 origin
header null 值,Play 不会用 access-control-allow-origin
header 响应。为了进行测试,您可以设置一个本地网络服务器,例如
cd c:\Users\XXX\XXX
python -m SimpleHTTPServer
然后您可以将文件加载为
因为我在这上面花了太多时间,这里是 Java 中 Play 2.12 的答案:
在app\filters\CorsFilter.java:
package filters;
import java.util.concurrent.CompletionStage;
import java.util.function.Function;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import akka.stream.Materializer;
import play.mvc.Filter;
import play.mvc.Http.RequestHeader;
import play.mvc.Result;
@Singleton
public class CorsFilter extends Filter {
@Inject
public CorsFilter(Materializer mat) {
super(mat);
}
@Override
public CompletionStage<Result> apply(Function<RequestHeader, CompletionStage<Result>> next, RequestHeader rh) {
return next.apply(rh).thenApply(result ->
{
return result.withHeaders(
"Access-Control-Allow-Origin" , "*",
"Access-Control-Allow-Methods" , "OPTIONS, GET, POST, PUT, DELETE, HEAD",
"Access-Control-Allow-Headers" , "Accept, Content-Type, Origin, X-Json, X-Prototype-Version, X-Requested-With",
"Access-Control-Allow-Credentials" , "true"
);
});
}
}
在您的 conf\application.conf 中,在某处添加以下行:
play.filters.enabled += filters.CorsFilter
在您的 conf\routes 中添加以下内容:
OPTIONS / controllers.OptionsController.options(path: String ?= "")
OPTIONS /*path controllers.OptionsController.options(path)
添加class controllers.OptionsController(在app\controllers\OptionsController.java):
package controllers;
import play.mvc.Controller;
import play.mvc.Result;
public class OptionsController extends Controller {
public Result options(String path) {
return ok("").withHeaders(
"Access-Control-Allow-Origin" , "*",
"Access-Control-Allow-Methods" , "GET, POST, PUT, DELETE, OPTIONS",
"Access-Control-Allow-Headers" , "Accept, Origin, Content-type, X-Json, X-Prototype-Version, X-Requested-With",
"Access-Control-Allow-Credentials" , "true",
"Access-Control-Max-Age" , Integer.toString(60 * 60 * 24)
);
}
}
我已经在本地部署了我的 Play 应用程序,并且在我的浏览器中通过 localhost:9000
访问我的 REST API 完美无缺。
但是,从 file:///C:/Users/XXX/XXX//index.html
执行 jQuery 脚本(见下文)时出现以下错误:
Failed to load resource: the server responded with a status of 403 (Forbidden)
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. The response had HTTP status code 403.
我按照 https://www.playframework.com/documentation/2.6.x/CorsFilter 下给出的说明进行操作。
我的build.sbt
:
libraryDependencies ++= Seq(
jdbc,
evolutions,
guice,
"com.h2database" % "h2" % "1.4.194",
javaJpa,
"org.hibernate" % "hibernate-core" % "5.2.5.Final",
filters
)
我的application.conf
:
play.filters.enabled += "play.filters.cors.CORSFilter"
play.filters.cors {
# allow all paths
pathPrefixes = ["/"]
# allow all origins (You can specify if you want)
allowedOrigins = null
allowedHttpMethods = ["GET", "POST", "PUT", "DELETE"]
# allow all headers
allowedHttpHeaders = null
}
注意:我尝试了 allowedOrigins = null
和 allowedOrigins = ["*"]
jQuery-脚本:
$.ajax({
'url' : 'http://localhost:9000/employee/' + user_id + '/weeklyWorkingHours',
'type' : 'GET',
'success' : function(data) {
console.log('Data: '+ JSON.stringify(data));
},
'error' : function(request,error)
{
console.log("Error: "+JSON.stringify(request));
}
});
Play 是这样说的:
[warn] p.f.c.CORSFilter - Invalid CORS request;Origin=Some(null);Method=GET;Access-Control-Request-Headers=None
尝试将其放入 application.conf(它将允许所有来源)
play.filters.cors.allowedOrigins = null
并且不要禁用 cors 过滤器
play.filters.enabled += "play.filters.cors.CORSFilter"
您将无法从本地文件中获取 CORS。浏览器向服务器发送一个 origin
header null 值,Play 不会用 access-control-allow-origin
header 响应。为了进行测试,您可以设置一个本地网络服务器,例如
cd c:\Users\XXX\XXX
python -m SimpleHTTPServer
然后您可以将文件加载为
因为我在这上面花了太多时间,这里是 Java 中 Play 2.12 的答案:
在app\filters\CorsFilter.java:
package filters; import java.util.concurrent.CompletionStage; import java.util.function.Function; import com.google.inject.Inject; import com.google.inject.Singleton; import akka.stream.Materializer; import play.mvc.Filter; import play.mvc.Http.RequestHeader; import play.mvc.Result; @Singleton public class CorsFilter extends Filter { @Inject public CorsFilter(Materializer mat) { super(mat); } @Override public CompletionStage<Result> apply(Function<RequestHeader, CompletionStage<Result>> next, RequestHeader rh) { return next.apply(rh).thenApply(result -> { return result.withHeaders( "Access-Control-Allow-Origin" , "*", "Access-Control-Allow-Methods" , "OPTIONS, GET, POST, PUT, DELETE, HEAD", "Access-Control-Allow-Headers" , "Accept, Content-Type, Origin, X-Json, X-Prototype-Version, X-Requested-With", "Access-Control-Allow-Credentials" , "true" ); }); }
}
在您的 conf\application.conf 中,在某处添加以下行:
play.filters.enabled += filters.CorsFilter
在您的 conf\routes 中添加以下内容:
OPTIONS / controllers.OptionsController.options(path: String ?= "") OPTIONS /*path controllers.OptionsController.options(path)
添加class controllers.OptionsController(在app\controllers\OptionsController.java):
package controllers; import play.mvc.Controller; import play.mvc.Result; public class OptionsController extends Controller { public Result options(String path) { return ok("").withHeaders( "Access-Control-Allow-Origin" , "*", "Access-Control-Allow-Methods" , "GET, POST, PUT, DELETE, OPTIONS", "Access-Control-Allow-Headers" , "Accept, Origin, Content-type, X-Json, X-Prototype-Version, X-Requested-With", "Access-Control-Allow-Credentials" , "true", "Access-Control-Max-Age" , Integer.toString(60 * 60 * 24) ); } }