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

时间:2017-08-08 02:07:48

标签: scala rest playframework cors preflight

我正在尝试绕过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"。我已经尝试将allowedOriginsallowedHttpMethodsallowedHttpHeaders 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组织 - 这应该不是那么困难。谢谢。

2 个答案:

答案 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"]"
}

现在一切正常!

video