【问题标题】:Play! 2.4: How to allow CORS from origin file://玩! 2.4:如何允许来自源文件的CORS://
【发布时间】:2015-12-07 04:01:50
【问题描述】:

我正在使用 play 2.4 创建一个公共 REST API。我添加了允许所有来源和标题的 CORS 过滤器。

从 application.conf 中查看:

play.filters {
  # CORS filter configuration
  cors {

    # The path prefixes to filter.
    pathPrefixes = ["/"]

    # 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

    # The exposed headers
    exposedHeaders = []

    # Whether to support credentials
    supportsCredentials = true

    # The maximum amount of time the CORS meta data should be cached by the client
    preflightMaxAge = 1 hour
  }
}

当我从经典浏览器(chrome/firefox 测试)调用 API 时,它工作得非常好,无论来源如何,我都允许。

但是当我尝试从 cordova 应用程序中调用它时(在 cordova 应用程序中,ajax 请求的来源是 file://),我收到一个 CORS 错误:No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'file://' is therefore not allowed access. The response had HTTP status code 403。好像我不允许 origin 'file://'

我尝试使用另一个 API,它允许 CORS (GET https://public.opencpu.org/ocpu/library/) 检查是否不是 cordova 阻止了请求,但它工作正常。所以我猜这个问题来自Play。

我尝试设置allowedOrigins = ["file://"],但它也不起作用......

有什么帮助吗?

编辑:这不是Cross origin GET from local file:// 的副本:我无法安装网络服务器,因为这是一个cordova 应用程序。这些文件从手机/平板电脑文件系统提供给 WebView。 这是一个 Play 框架特定的问题,我以前对旧版本没有任何问题。也许可以修改默认的 CorsFilter 以允许源文件://

编辑 2:请求后,这是我用于自定义 scala 过滤器的(非常简单的)代码。

// CORSFilter.scala
package filters
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import play.api.mvc._
import play.mvc.Http

/**
  * Allow CORS from anywhere, any method
  */
class CORSFilter extends EssentialFilter {
  def apply(nextFilter: EssentialAction) = new EssentialAction {
    def apply(requestHeader: RequestHeader) = {
        nextFilter(requestHeader)
          .map { result =>
            if (requestHeader.method.equals("OPTIONS")) {
              Results.Ok.withHeaders(
                Http.HeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN -> "*",
                Http.HeaderNames.ACCESS_CONTROL_ALLOW_HEADERS -> "X-Requested-With, Accept, Content-Type",
                Http.HeaderNames.ACCESS_CONTROL_ALLOW_METHODS -> "HEAD,GET,POST,PUT,PATCH,DELETE")
            } else {
              result.withHeaders(
                Http.HeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN -> "*",
                Http.HeaderNames.ACCESS_CONTROL_ALLOW_HEADERS -> "X-Requested-With, Accept, Content-Type",
                Http.HeaderNames.ACCESS_CONTROL_ALLOW_METHODS -> "HEAD,GET,POST,PUT,PATCH,DELETE",
                Http.HeaderNames.ACCESS_CONTROL_EXPOSE_HEADERS -> "X-Custom-Header-To-Expose")
            }
          }
    }
  }
}

请注意,我只在开发模式下使用它,它有一些问题。例如,如果在运行时未捕获异常,则响应将没有 CORS 标头,因为未应用过滤器。但如果这是针对 cordova 应用程序,它应该可以正常工作。

【问题讨论】:

  • 你的cordova实现代码是什么样的?
  • 您好,这是一个副本:stackoverflow.com/questions/8192159/…
  • @Saar 我为你标记了它:)
  • 安装本地网络服务器....有很多方法可以做到,而且不会花很长时间
  • 这不是重复的萨尔,我的问题是具体的。我只想授权来自原始文件:// 的请求,它曾经在旧版本中工作。我无法安装本地服务器,因为这是一个 cordova 应用程序 charlitfl,文件从移动文件系统提供给 WebView

标签: javascript playframework cors


【解决方案1】:

好的,问题出在Play框架中的这行代码:https://github.com/playframework/playframework/blob/master/framework/src/play-filters-helpers/src/main/scala/play/filters/cors/AbstractCORSPolicy.scala#L322

由于 URI 是“file://”,因此 URI 的域/主机为 null,因此 new URI 会引发错误,然后 Play 返回 403 错误。要解决这个问题,我们需要修补框架或尝试将源更改为“file://”。

我为我的用例找到了一种解决方法:在 Play 上禁用 CORS。然后,当我从我的科尔多瓦应用程序中使用 ajax 时,不会检查来源。

这个解决方法的问题是,如果我出于任何原因想在我的 Play 项目上启用 CORS,cordova 应用程序将无法运行,因为 Play 将检查来源并拒绝它。

【讨论】:

  • 您能解释一下如何禁用 CORS 吗?
  • 我已经启用了播放过滤器CorsFilter。当我的科尔多瓦应用程序不需要它来工作时,我只是将其删除。然后的问题是,如果我在浏览器上测试我的科尔多瓦应用程序,如果我没有禁用 chrome 中的跨域安全性,我会遇到 CORS 错误。所以后来我只是制作了自己的 CORSFilter,它为每个请求添加所需的标头而无需任何检查。
  • @SebT 我面临同样的情况。您能否分享您制作的 CORSFilter 的代码?
猜你喜欢
  • 2020-12-29
  • 2021-04-28
  • 2013-11-28
  • 2021-05-13
  • 1970-01-01
  • 1970-01-01
  • 2017-04-27
  • 2021-11-11
  • 2013-01-29
相关资源
最近更新 更多