Play Framework 2.4.x 中的 CORS 疑难解答
Posted
技术标签:
【中文标题】Play Framework 2.4.x 中的 CORS 疑难解答【英文标题】:Trouble-shooting CORS in Play Framework 2.4.x 【发布时间】:2015-11-05 15:59:07 【问题描述】:我有一个提供 JSON/HTTP API 的 java play framework 2.4.x Web 应用程序。当我运行我的前端 html/JS file:///Users/nize/tmp/index.html
在 http://localhost:9000
上调用 API 时,chrome 显示
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 Documentation 中的说明配置了网络应用程序:
更新为build.sbt
将类Filters.java
添加到项目的根目录(也尝试过/app
)
在application.conf
中添加了以下节:
play.filters.cors
allowedOrigins = ["*","http://localhost"]
#allowedHttpMethods = ["GET", "POST"]
#allowedHttpHeaders = ["Accept"]
#preflightMaxAge = 3 days
我错过了什么?
编辑: 症状看起来与Other very similar *** post 相同或相似。该问题通过重新配置安装在计算机上的 Cisco AnyConnect *** 得到解决。但是,我没有安装该软件。
【问题讨论】:
在我查看下面的答案之前,您的问题已经帮助了我。我只实现了文档中说明的最后一部分(在application.conf
中配置 CORS 过滤器),缺少前两个(更新 build.sbt
并添加 Filters.java
)。所以我一直在玩游戏,直到我偶然发现你的问题总结了我从官方文档中遗漏的步骤,以及下面的 Radium 答案,链接到reference.conf
。顺便说一句,我使用的是 Firefox,并且在 Chrome 上也成功测试过,所以这对我来说不是 Chrome 特有的问题,甚至不应该是。
@nize 你能解决这个问题吗?我有完全相同的问题。我还定义了一个控制器方法来处理 OPTIONS 请求,但无济于事。我总是使用 Ajax 和 Postman 得到 403
【参考方案1】:
首先将这些行(配置)添加/编辑到您的 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 ;
您可以参考official documentation了解更多信息。
【讨论】:
非常适合我,谢谢。请注意,默认 app.conf 文件已经有 cors 配置 - 这只是取消注释/编辑相关设置的情况。 类型不匹配:无法从 CORSFilter 转换为 EssentialFilter @cyril 你用的是什么播放版本? corsFilter.asJava() 2.5 版没问题,谢谢【参考方案2】: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()
;
【讨论】:
【参考方案3】:我认为CORS filter in Play 不起作用!我一步一步地跟着,但不知何故,我总是在 Ajax 调用中的浏览器(Chrome 和 Firefox)中得到 HTTP-403。问题是我什至没有在服务器端获得堆栈跟踪。我认为 CORS 过滤器中的 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)
这是日志过滤器(来源:Play!框架)
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 $requestTimems and returned $result.header.status")
result.withHeaders(
"Request-Time" -> requestTime.toString,
"Access-Control-Allow-Origin" -> "*" // Added this header
)
【讨论】:
【参考方案4】:我遇到了类似的问题,我收到了 403 的请求。我通过删除:
allowedHttpHeaders=["Accept"]
他们在示例配置中使用。但是,我仍然不清楚这对安全的影响是什么,所以 YMMV。
【讨论】:
这对我也有用。我也不确定这会带来什么安全隐患。【参考方案5】:这可能无法解决发帖者的问题,但是当我有相同的症状时,它为我解决了问题,我发布它以防它可以帮助处于相同情况的其他人。
我实际上误解了 CORS 的工作原理。我有两个独立的 Play 应用程序,一个带有 REST API,另一个带有使用 REST API 的 Web 界面。我按照问题中提到的文档页面中的说明进行操作,但我的错误是我在 Web 界面应用程序上进行了操作。当我改为在 REST API 应用程序上执行此操作时,它立即生效。
【讨论】:
【参考方案6】:我在遵循相同的文档时遇到了同样的问题。
问题在于您使用的这个 CORS 过滤器:
allowedOrigins = ["*","http://localhost"]
如果您想允许所有来源使用:
allowedOrigins = null
allowedHttpMethods
也一样
这是根据documentation
引用:
允许的来源。如果为 null,则允许所有来源。
allowedOrigins = null
希望这会有所帮助!
【讨论】:
【参考方案7】:它在 Firefox 中有效吗? Chrome 对从本地文件运行 Ajax 有一些限制,例如,请参阅 this link。如果是 Chrome 特定的,您可以使用命令行开关启动 Chrome 以消除限制。
【讨论】:
好点。我也尝试使用 firefox (MacOS),但我得到了 403(禁止)。 对于我在 chrome、firefox 和 explorer 中工作的配置:***.com/questions/38315501/…以上是关于Play Framework 2.4.x 中的 CORS 疑难解答的主要内容,如果未能解决你的问题,请参考以下文章
Play Framework [2.4.x] 如何在子模块的路由文件中处理公共资产
Play Framework 2.4.x - 覆盖默认的 Actor 系统创建
迁移到 2.4.x (Java) 后在 Play Framework 中运行测试时出错