Play Framework 2.8.15中使用HOCON变量配置allowedOrigins引发的CORS问题
结合你的配置和遇到的错误,我来梳理几个关键的排查和修复方向:
1. 调整CORS过滤器的执行顺序
你的play.filters.enabled列表里,CORSFilter排在了GzipFilter、MetricsFilter之后。Play的过滤器是按声明顺序执行的,如果前面的过滤器提前返回了响应(比如错误响应),CORS头可能根本没机会被添加。
把play.filters.cors.CORSFilter移到列表最前面,确保它最先处理请求:
play.filters.enabled = [ "play.filters.cors.CORSFilter", "play.filters.gzip.GzipFilter", "com.kenshoo.play.metrics.MetricsFilter", "http.filters.ClusterStatusFilter" ]
2. 修正Origin地址的格式问题
注意到你的配置里server1.host末尾带了斜杠:"http://localhost:9000/",但浏览器发送的Origin是https://localhost:9000(不带斜杠),这会导致Origin完全不匹配,CORS策略直接拦截。
先把所有server host的末尾斜杠去掉:
server1.host="http://localhost:9000" server2.host="http://localhost:2000" server3.host="http://localhost:11000"
另外,错误里的Origin是https协议,但你的配置里是http,如果实际部署用的是HTTPS,要同步修改server变量里的协议为https。
3. 确保CORS模块已正确启用
虽然Play 2.8默认启用CORS模块,但如果你的配置里禁用了某些核心模块,可能间接影响了它。可以显式在play.modules.enabled里添加:
play.modules.enabled += "play.modules.cors.CORSModule"
4. 验证配置的实际解析结果
即使你确认变量已被解析,也可以在应用启动时打印CORS的实际生效配置,确保allowedOrigins是你预期的列表。比如在你的StartUpModule里添加调试代码(Scala示例):
import play.api.inject._ import play.api.Configuration import play.filters.cors.CORSConfig class StartUpModule extends Module { override def bindings(environment: play.api.Environment, configuration: Configuration): Seq[Binding[_]] = { val corsConfig = configuration.get[CORSConfig]("play.filters.cors") println(s"[DEBUG] CORS Allowed Origins: ${corsConfig.allowedOrigins}") // 保留原有启动逻辑 Seq.empty } }
启动应用后查看控制台输出,确认解析后的Origin列表是否包含请求的https://localhost:9000。
5. 排查自定义组件的干扰
你用到了自定义的ClusterStatusFilter、BasicActionCreator和WebHttpRequestHandler,这些组件可能在处理请求时修改了响应头,或者提前终止了请求流程。可以暂时注释掉这些自定义配置,测试CORS是否正常工作,逐步定位问题来源。
先从调整过滤器顺序和修正Origin格式开始,这两个是最常见的触发原因,应该能解决大部分情况。
内容的提问来源于stack exchange,提问作者Oana-Elena Danescu

