Dribel
Dribel

Reputation: 495

Using cors across two independently running local apps

I have two applications running indepepently, one taking care of my backend (written in Scala Play) then other one being my frontend (Angular with a static Node server).

I try to request data on my frontend through a form from my Scala Play app.

this.insertionOrder = function(){
          $http({
            method: 'POST',
            url: '//localhost:9000/insertsupplier',
            header: {
              'Content-type': 'application/json',
              'Access-Control-Allow-Origin' : '*',
              'Access-Control-Allow-Methods' : 'POST, GET, OPTIONS'
            },
            data:{
              'supplier_id': 1,
              'suppliername': 'xxx',
              'supplier_address': 'xxx xxx xxx xxx',
              'contact': '[email protected]',
              'datecreated': '2017-10-15T09:45:00.000UTC+00:00'
            }
          }).then(function(response){
            console.log(response);
            return response.data
          }, function(err){
            console.log(err)
          });
        };

and my play app looks like this:

Controller:

  def insertsupplier = Action(parse.json) { implicit request =>
    val json = request.body
    val sup: Supplier = json.as[Supplier]
    sup.insertSql(con)
    Ok("test")
  }

my build.sbt contains filters:

libraryDependencies ++= Seq(
  cache ,
  ws,
  jdbc,
  filters
)

and the MyFilters.scala

class MyFilters (implicit inj:Injector)  extends HttpFilters with Injectable {
  implicit val as = inject[ActorSystem]
  implicit val mat = ActorMaterializer()
  val gzip = new GzipFilter()
  val csrf = inject[CSRFFilter]
  val cors = inject[CORSFilter]
  //println(s"csrf: ${csrf.tokenProvider}")
  //println(s"csrf: ${csrf.tokenProvider.generateToken}")
  def filters = Seq(gzip,cors,csrf)
}

and finally my application.conf

play.filters.cors {
  pathPrefixes = ["*"]
  allowedOrigins = ["http://localhost:3000","https://localhost:3000","http://localhost:3000/*","https://localhost:3000/*"]
  allowedHttpMethods = ["GET", "POST", "OPTIONS"]
  allowedHttpHeaders = ["Accept"]
 # preflightMaxAge = 1 hour
}

play.filters.csrf {
  cookie.name = "XSRF-TOKEN"
  header.name = "X-XSRF-TOKEN"
}

play.http.filters = "filters.MyFilters"

I keep getting the error "XMLHttpRequest cannot load http://localhost:9000/insertsupplier. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 500."

I feel that first my CORS setup is wrong anyway --> What needs to be changed? I am new to this.

And am I even able to use cors in order to access data from localhost?

Upvotes: 1

Views: 769

Answers (1)

sideshowbarker
sideshowbarker

Reputation: 88036

It may be that there’s nothing wrong at all with your CORS setup, because the “The response had HTTP status code 500” part of the error message indicates that the actual immediate problem is that an OPTIONS request to your server caused some unexpected failure on the server side.

From just the code snippets in the question, it’s not possible to tell what might be causing that 500 failure in the server side. It may be completely unrelated to your CORS config.

But regardless, you should drop the parts of your frontend code that are adding the header 'Access-Control-Allow-Origin' : '*', and 'Access-Control-Allow-Methods'. Those headers are response headers that must be sent from the server side, not from frontend code.

But the 'Content-type': 'application/json' part of your frontend code is valid, and assuming it’s actually necessary in order to get the expected response from the server, there’s no way you can make your request without triggering browsers to do a CORS preflight OPTIONS request.

But if the CORS preflight OPTIONS request fails, the browser never gets around to trying the POST request your code is actually attempting to send. And if your backend responds to that OPTIONS request with a 500 response, then the preflight fails. It must instead respond with a 200 or 204.

Upvotes: 1

Related Questions