title: Play! 2.4: How to allow CORS from origin file://
body: <p>I'm using play 2.4 to make a public REST API. I added the CORS filter allowing all origins and headers. </p>
  
  <p>See from application.conf:</p>
  
  <pre><code>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
    }
  }
  </code></pre>
  
  <p>It works perfectly fine when I call the API from a classic browser (chrome/firefox tested), regardless of the origin as I allowed all.</p>
  
  <p>BUT when I try to call it form a cordova application (in cordova apps, the origin of ajax requests are <code>file://</code>), I get a CORS error: <code>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</code>. As if I didn't allow origin 'file://'</p>
  
  <p>I tried to consume another API that allows CORS (GET <a href="https://public.opencpu.org/ocpu/library/" rel="noreferrer">https://public.opencpu.org/ocpu/library/</a>) to check if it wasn't cordova that blocked the request but it worked fine. So I guess the problem comes from Play. </p>
  
  <p>I tried to set <code>allowedOrigins = ["file://"]</code> but it doesn't work either... </p>
  
  <p>Any help please?</p>
  
  <p>EDIT: This isn't a duplicate of <a href="https://stackoverflow.com/questions/8192159/cross-origin-get-from-local-file">Cross origin GET from local file://</a> : 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://</p>
  
  <p>EDIT 2: After it's been requested, here's the (very simple) code I use for my custom scala filter.</p>
  
  <pre><code>// 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 =&gt;
              if (requestHeader.method.equals("OPTIONS")) {
                Results.Ok.withHeaders(
                  Http.HeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN -&gt; "*",
                  Http.HeaderNames.ACCESS_CONTROL_ALLOW_HEADERS -&gt; "X-Requested-With, Accept, Content-Type",
                  Http.HeaderNames.ACCESS_CONTROL_ALLOW_METHODS -&gt; "HEAD,GET,POST,PUT,PATCH,DELETE")
              } else {
                result.withHeaders(
                  Http.HeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN -&gt; "*",
                  Http.HeaderNames.ACCESS_CONTROL_ALLOW_HEADERS -&gt; "X-Requested-With, Accept, Content-Type",
                  Http.HeaderNames.ACCESS_CONTROL_ALLOW_METHODS -&gt; "HEAD,GET,POST,PUT,PATCH,DELETE",
                  Http.HeaderNames.ACCESS_CONTROL_EXPOSE_HEADERS -&gt; "X-Custom-Header-To-Expose")
              }
            }
      }
    }
  }
  </code></pre>
  
  <p>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.</p>