Option Request Fails With 404

- 1 answer

I am trying to send a GET request from my frontend to an API application. Both are running on my local machine. This is how it's built right now:

backend <===> frontend <=x=> API application

All three parts are running independently from each other in their own docker container and are only communicating with each other via HTTP-requests.

As shown in the top image, the connection between backend and frontend works fine, but between frontend and API application does not.

The stack consists of:

  • frontend: Node server with vue-js and for requests I use axios
  • API application: Scala with Play Framework 2.5.14

The API application itself works just find when I send a request to her via curl like this:

curl -X GET api-application.docker/api/user?userId=1 \
-H "Authorization: key" -H "Accept: Application/Json"

But when I call it from frontend, I get a 404 on the OPTIONS call. It also gives me a warning in Firefox related to CORS header Access-Control-Allow-Origin:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the
remote resource at http://api-application.docker:9000/api/user?userId=1
(Reason: CORS header ‘Access-Control-Allow-Origin’ missing).

Therefore I first went into the api application's application.conf and added

play.filters.cors {
  allowedOrigins = ["*"]

I also tried to exchange the asterisk for http://frontend.docker:8080

This didn't work, so I deleted that entry again and added this line instead:

play.filters.disabled += "play.filters.cors.CORSFilter"

Still no change at all. Now I am wondering if I misunderstood the connection between OPTIONS and CORS? Or did I turn it off wrong? Can anyone help me out?

EDIT: More stuff I tried while waiting for answers, all without success:

I changed the entry in application.conf to:

play.filters.cors {
  allowedOrigins = null


404 on OPTIONS request indicates your CORSFilter is not enabled. Since you are using Play 2.5 you can enable it by adding

libraryDependencies += filters 

to your build.sbt, and by creating the following app/Filters.scala file:

import javax.inject.Inject
import play.api.http.DefaultHttpFilters
import play.filters.cors.CORSFilter

class Filters @Inject() (corsFilter: CORSFilter)
  extends DefaultHttpFilters(corsFilter)

By default everything is allowed so there is no need to modify application.conf until you decide to start locking down access. You should NOT add play.filters.disabled += "play.filters.cors.CORSFilter" as this disables CORS support.

The reason why your curl request works fine is because non-browser HTTP clients do not enforce Same-origin policy (see related SO answer), thus CORS does not apply in the case of curl.

404 on OPTIONS request means that the following route is not found:

OPTIONS api-application.docker/api/user

The browser automatically sends this preflight request before sending the corresponding GET request. This OPTIONS route will be automatically taken care of by Play's CORS support once enabled.