我正在尝试绕过Scala / Play 2.6.x中一个简单的“hello world”样式REST API的CORS错误,并且我已经尝试了我能想到的所有内容。据我所知,在互联网上没有一个好的解决方案或示例,所以即使这应该是一个简单的解决方案,那么任何有良好解决方案的人都会通过完整发布来帮助我。我只是尝试将localhost:3000
(使用axios的反应应用程序)的帖子请求发送到我的Scala / Play框架所在的localhost:9000
。
错误
我在客户端获得的错误如下:
XMLHttpRequest cannot load http://localhost:9000/saveTest.
Response to preflight request doesn't pass access control check:
No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:3000' is therefore not allowed
access. The response had HTTP status code 403.
我在服务器端遇到的错误是
success] Compiled in 1s
--- (RELOAD) ---
[info] p.a.h.EnabledFilters - Enabled Filters
(see <https://www.playframework.com/documentation/latest/Filters>):
play.filters.csrf.CSRFFilter
play.filters.headers.SecurityHeadersFilter
play.filters.hosts.AllowedHostsFilter
play.filters.cors.CORSFilter
[info] play.api.Play - Application started (Dev)
[warn] p.f.c.CORSFilter - Invalid CORS
request;Origin=Some(http://localhost:3000);
Method=OPTIONS;Access-Control-Request-Headers=Some(content-type)
我的代码
我的application.conf
文件
# https://www.playframework.com/documentation/latest/Configuration
play.filters.enabled += "play.filters.cors.CORSFilter"
play.filters.cors {
pathPrefixes = ["/"]
allowedOrigins = ["http://localhost:3000", ...]
allowedHttpMethods = ["GET", "POST", "PUT", "DELETE"]
allowedHttpHeaders = ["Accept"]
preflightMaxAge = 3 days
}
我尝试将pathPrefixes
更改为/saveTest
(我的终点),并尝试将allowedOrigins
更改为'https://localhost'
。我尝试过更改allowedHttpHeaders="Allow-access-control-allow-origin"
。我已经尝试将allowedOrigins
,allowedHttpMethods
和allowedHttpHeaders
all设置为null,根据文档(https://www.playframework.com/documentation/2.6.x/resources/confs/filters-helpers/reference.conf)应该允许所有内容(应该pathPrefixes=["/"]
我的build.sbt如下,所以应该将过滤器添加到libraryDependencies:
name := """scalaREST"""
organization := "com.example"
version := "1.0-SNAPSHOT"
lazy val root = (project in file(".")).enablePlugins(PlayScala)
scalaVersion := "2.12.2"
libraryDependencies += guice
libraryDependencies += "org.scalatestplus.play" %% "scalatestplus-play" % "3.1.0" % Test
libraryDependencies += filters
根据此处提供的文档:https://www.playframework.com/documentation/2.6.x/Filters#default-filters您可以设置默认过滤器,如下所示:
import javax.inject.Inject
import play.filters.cors.CORSFilter
import play.api.http.{ DefaultHttpFilters, EnabledFilters }
class Filters @Inject()(enabledFilters: EnabledFilters, corsFilter: CORSFilter)
extends DefaultHttpFilters(enabledFilters.filters :+ corsFilter: _*)
我不确定我的项目究竟应该放在哪里 - 它没有说明,但是从其他stackoverflow答案中我假设它应该放在我的目录的根目录中(即/app
) 。这就是我说的地方。
最后,有一个异乎寻常的stackoverflow响应,据说把这个类放在我的控制器中,并将其作为函数添加到我的OK响应中
implicit class RichResult (result: Result) {
def enableCors = result.withHeaders(
"Access-Control-Allow-Origin" -> "*"
, "Access-Control-Allow-Methods" ->
"OPTIONS, GET, POST, PUT, DELETE, HEAD"
// OPTIONS for pre-flight
, "Access-Control-Allow-Headers" ->
"Accept, Content-Type, Origin, X-Json,
X-Prototype-Version, X-Requested-With"
//, "X-My-NonStd-Option"
, "Access-Control-Allow-Credentials" -> "true"
)
}
毋庸置疑,这不起作用。
WRAP UP
这是我当前scala项目的后端。
https://github.com/patientplatypus/scalaproject1/tree/master/scalarest
如果可以的话,请展示一个CORS实施的完整工作示例 - 我无法获得任何我可以在网上找到的工作。我可能会将此作为文档请求提交给Play Framework组织 - 这应该不是那么困难。谢谢。
答案 0 :(得分:0)
您的预检请求失败,因为您有一个Content-Type标头集
将content-type
添加到allowedHttpHeaders
中的application.conf
,如此
#application.conf
play.filters.cors {
#other cors configuration
allowedHttpHeaders = ["Accept", "Content-Type"]
}
答案 1 :(得分:0)
我也有这个问题,我在application.conf中添加了这些代码
play.filters.enabled += "play.filters.cors.CORSFilter"
play.filters.cors {
allowedHttpMethods = ["GET", "HEAD", "POST"]
allowedHttpHeaders = ["Accept", "Content-Type"]"
}
现在一切正常!