在 Scala Play Framework v2.6.x 中获取 cors 错误

Pet*_*and 5 rest scala cors playframework preflight

我正在尝试解决 Scala/Play 2.6.x 中一个简单的“hello world”样式 REST API 的 CORS 错误,并且我已经尝试了此时我能想到的所有方法。据我所知,在互联网上找不到好的解决方案或示例,所以即使这应该是一个简单的解决方案,那么任何有好的解决方案的人都会通过完整发布来真正帮助我。我只是想从localhost:3000(使用 axios 的反应应用程序)向localhost:9000我的 Scala/Play 框架所在的位置发送一个 post 请求。

错误

我在客户端遇到的错误如下:

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.
Run Code Online (Sandbox Code Playgroud)

我在服务器端遇到的错误是

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)
Run Code Online (Sandbox Code Playgroud)

我的代码

我的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
}
Run Code Online (Sandbox Code Playgroud)

我尝试更改pathPrefixes/saveTest(我的端点),并尝试更改allowedOrigins为简单的'https://localhost'. 我试过改变allowedHttpHeaders="Allow-access-control-allow-origin"。根据文档(https://www.playframework.com/documentation/2.6.x/resources/confs/filters-helpers/reference.confallowedOrigins,我已经尝试将,allowedHttpMethodsallowedHttpHeadersall设置为 null应该允许一切(理应如此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
Run Code Online (Sandbox Code Playgroud)

根据此处提供的文档: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: _*)
Run Code Online (Sandbox Code Playgroud)

我不确定它应该在我的项目中的确切位置 - 它没有说,但是从其他 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"
    )
  }
Run Code Online (Sandbox Code Playgroud)

不用说,这行不通。

包起来

这是我当前 Scala 项目的后端。

https://github.com/patientplatypus/scalaproject1/tree/master/scalarest

如果可以,请展示一个 CORS 实现的完整工作示例 - 我无法在网上找到任何可以工作的东西。我可能会将此作为文档请求提交给 Play Framework 组织 - 这应该不会那么困难。谢谢你。

Sal*_*lah 3

您的预检请求失败,因为您设置了 Content-Type 标头

添加content-typeallowedHttpHeadersapplication.conf喜欢的地方

#application.conf

play.filters.cors {
  #other cors configuration
  allowedHttpHeaders = ["Accept", "Content-Type"]
} 
Run Code Online (Sandbox Code Playgroud)