玩! 2.4:如何从源文件中允许CORS:// [英] Play! 2.4: How to allow CORS from origin file://

查看:66
本文介绍了玩! 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错误:请求的资源上没有'Access-Control-Allow-Origin'标头。因此不允许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...

请帮忙吗?

编辑:这不是来自本地文件的来源GET:// :我无法安装网络服务器,因为这是一个科尔多瓦申请。这些文件从手机/平板电脑文件系统提供给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")
            }
          }
    }
  }
}

请注意,我只在de中使用它发展模式,它有一些问题。例如,如果在运行时未捕获到异常,则响应将不具有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://'.

我找到了一个解决方法来解决我的用例:禁用CORS on玩。然后,当我使用来自我的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天全站免登陆