在Play Framework 2.4.x中解决CORS问题

我有一个java play框架2.4.x Web应用程序,提供JSON / HTTP API。 当我运行我的前端HTML / JS file:///Users/nize/tmp/index.htmlhttp://localhost:9000 chrome file:///Users/nize/tmp/index.html调用API

 XMLHttpRequest cannot load http://localhost:9000. 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. 

我已按照Play Framework 2.4.x CORS文档中的说明配置了Web应用程序:

  • 更新到build.sbt
  • 将类Filters.java添加到项目的根目录(也尝试过/app
  • 将以下节添加到application.conf

    play.filters.cors {allowedOrigins = [“*”,“ http:// localhost ”] #allowedHttpMethods = [“GET”,“POST”] #allowedHttpHeaders = [“Accept”] #preflightMaxAge = 3 days}

我错过了什么?

编辑:症状看起来与其他非常相似的stackoverflowpost相同或类似。 通过重新配置计算机上安装的Cisco AnyConnect VPN解决了该问题。 但是,我没有安装该软件。

首先在conf / application.conf中添加/编辑这些行(配置)

  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 } 

(请注意,以“#”开头的行是注释行。)

然后转到build.sbt并添加此行。

 libraryDependencies += filters 

最后创建一个名为“Filters.java”的Java类,并将其包含在根目录(/ app)中。

 import play.api.mvc.EssentialFilter; import play.filters.cors.CORSFilter; import play.http.HttpFilters; import javax.inject.Inject; public class Filters implements HttpFilters { @Inject CORSFilter corsFilter; public EssentialFilter[] filters() { return new EssentialFilter[] { corsFilter }; } } 

您可以参考官方文档以获取更多信息。

我在遵循相同的文档时遇到了同样的问题。

问题在于您使用过的CORSfilter:

 allowedOrigins = ["*","http://localhost"] 

如果您想允许所有来源使用:

 allowedOrigins = null 

allowedHttpMethods采用相同的allowedHttpMethods

这是根据文档

去引用:

允许的起源。 如果为null,则允许所有原点。

 allowedOrigins = null 

希望这可以帮助!

我认为Play中的CORSfilter不起作用! 我一步一步地跟着,但不知何故,我总是在Ajax调用中在浏览器(Chrome和Firefox)中获得HTTP-403。 问题是我甚至没有在服务器端获得堆栈跟踪。 我认为CORSfilter中的DefaultHttpErrorHandler以某种方式吞噬了它。 在响应“Access-Control-Allow-Origin”标题丢失,所以我只是手动添加。

 class Filters @Inject() (corsFilter: CORSFilter, log: LoggingFilter) extends HttpFilters { def filters = { // CORS filter does not work //Seq(corsFilter, log) Seq(log) } } 

这是日志filter(Credit:Play!framework)

 class LoggingFilter extends Filter { def apply(nextFilter: RequestHeader => Future[Result])(requestHeader: RequestHeader): Future[Result] = { val startTime = System.currentTimeMillis nextFilter(requestHeader).map { result => val endTime = System.currentTimeMillis val requestTime = endTime - startTime Logger.info(s"${requestHeader.method} ${requestHeader.uri} " + s"took ${requestTime}ms and returned ${result.header.status}") result.withHeaders( "Request-Time" -> requestTime.toString, "Access-Control-Allow-Origin" -> "*" // Added this header ) } } } 

我遇到了类似的问题,我的请求是403。 我通过删除以下内容解决了问题:

 allowedHttpHeaders=["Accept"] 

他们在示例配置中使用它们。 然而,我仍然不清楚它的安全含义是什么,所以YMMV。

它在Firefox中有效吗? Chrome对从本地文件运行Ajax有一些限制,例如,请参阅此链接 。 如果它是特定于Chrome的,您可以使用命令行开关启动Chrome以删除限制。

这可能无法解决海报的问题,但是当我遇到相同的症状时它解决了我的问题,而且我发布它以防它可以在相同的情况下帮助其他人。

我实际上误解了CORS是如何工作的。 我有两个独立的Play应用程序,一个带有REST API,另一个带有使用REST API的Web界面。 我按照问题中提到的文档页面中的说明进行操作,但我的错误是我在Web界面应用程序中执行了此操作。 当我在REST API应用程序上执行此操作时,它立即起作用。

 filters = "filters.Filters" play.filters { cors { # 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 } } public class Filters implements HttpFilters { @Inject private CORSFilter corsFilter; public EssentialFilter[] filters() { return new EssentialFilter[] { corsFilter.asJava() }; } }