玩!2.4:如何允许来自原始文件的 CORS:// [英] Play! 2.4: How to allow CORS from origin file://

查看:22
本文介绍了玩!2.4:如何允许来自原始文件的 CORS://的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 play 2.4 来制作公共 REST API.我添加了允许所有来源和标题的 CORS 过滤器.

I'm using play 2.4 to make a public REST API. I added the CORS filter allowing all origins and headers.

从 application.conf 中看到:

See from 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 时,它工作得非常好,无论来源如何,我都允许.

It works perfectly fine when I call the API from a classic browser (chrome/firefox tested), regardless of the origin as I allowed all.

但是当我尝试从cordova应用程序中调用它时(在cordova应用程序中,ajax请求的来源是file://),我收到一个CORS错误:No 'Access-Control-Allow-Origin' 标头存在于请求的资源上.因此,不允许访问源 'file://'.响应具有 HTTP 状态代码 403.好像我不允许来源 'file://'

BUT when I try to call it form a cordova application (in cordova apps, the origin of ajax requests are file://), I get a CORS error: 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. As if I didn't allow origin 'file://'

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

I tried to consume another API that allows CORS (GET https://public.opencpu.org/ocpu/library/) to check if it wasn't cordova that blocked the request but it worked fine. So I guess the problem comes from Play.

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

I tried to set allowedOrigins = ["file://"] but it doesn't work either...

有什么帮助吗?

这不是 从本地文件跨源获取的副本:// :我无法安装网络服务器,因为这是一个cordova 应用程序.文件从手机/平板电脑文件系统提供给 WebView.这是一个 Play 框架特定的问题,我以前在旧版本上没有问题.也许可以修改默认的 CorsFilter 以允许原始文件://

This isn't a duplicate of Cross origin GET from local file:// : I can't install a webserver as this is a cordova application. The files are served from the phone/tablet file system to the WebView. This is a Play framework specific question, I used to have no problems with an older version. Maybe the default CorsFilter can be modified to allow origin file://

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

EDIT 2: After it's been requested, here's the (very simple) code I use for my custom scala filter.

// 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 应用程序,它应该可以正常工作.

Note that I only use this in development mode and it has some issues. For exemple if an exception is not caught at runtime, the response won't have the CORS headers because the filter is not applied. But if this is for a cordova application, it should work fine enough.

推荐答案

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

Ok, the problem comes from this line of code in the Play framework: https://github.com/playframework/playframework/blob/master/framework/src/play-filters-helpers/src/main/scala/play/filters/cors/AbstractCORSPolicy.scala#L322

由于 URI 是 'file://',URI 的域/主机为空,所以 new URI 抛出错误,然后 Play 返回 403 错误.要解决此问题,我们需要修补框架或尝试将源更改为file://".

As the URI is 'file://', the domain/host of the URI is null so new URI throws an error and then Play returns a 403 error. To fix this we need to patch the framework or try to change the origin to 'file://'.

我找到了适用于我的用例的解决方法:在 Play 中禁用 CORS.然后,当我从我的cordova 应用程序中使用ajax 时,不会检查来源.

I found a workaround for my use case: disable CORS on Play. Then when I use ajax from my cordova app, the origin isn't checked.

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

The problem with this workaround is that if I want to enable CORS on my Play project for any reason, the cordova app won't work since Play will check the origin and reject it.

这篇关于玩!2.4:如何允许来自原始文件的 CORS://的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆