Ad

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
}
Ad

Answer

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.

Ad
source: stackoverflow.com
Ad