Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CORS response headers not working in Spray when requested from browser

I was attempting to implement CORS support on a Spray server (version 1.1-20131011 where cors headers are already supported).

Currently, the server code looks like this:

trait DefaultCORSDirectives { this: Directives =>
  def defaultCORSHeaders = respondWithHeaders(
      `Access-Control-Allow-Origin`(AllOrigins),
      `Access-Control-Allow-Methods`(HttpMethods.GET, HttpMethods.POST, HttpMethods.OPTIONS, HttpMethods.DELETE,
      HttpMethods.CONNECT, HttpMethods.DELETE, HttpMethods.HEAD, HttpMethods.PATCH, HttpMethods.PUT, HttpMethods.TRACE),
      `Access-Control-Allow-Headers`("Origin, X-Requested-With, Content-Type, Accept, Accept-Encoding, Accept-Language, Host," +
    " Referer, User-Agent, Overwrite, Destination, Depth, X-Token, X-File-Size, If-Modified-Since, X-File-Name, Cache-Control"),
      `Access-Control-Allow-Credentials`(true),
      `Access-Control-Max-Age`(3600)
    )
}

and is used like this

  defaultCORSHeaders {
      options {
        complete {
          StatusCodes.OK
        }
      } ~
      post {
        path("path") {
          //response
      }
   }

The responses for both POST and OPTIONS methods are as expected when using curl. However from browser, I get Origin is not allowed by Access-Control-Allow-Origin (Chrome) or Error 415 Unsupported Media Type (Firefox) and it seems the POST request is not even sent at all.

The requesting jQuery code is simply as follows:

$(document).ready(function () {
        $.post(url,
            {
               'params': "params",
            },
            function (data) {
                //handle response
            }
    );
});

I have read the CORS spec and all the resources I could find, tried any possible combination of the Access-Control-Allow- headers (with and without Access-Control-Allow-Credentials, different content of Access-Control-Allow-Headers and Access-Control-Allow-Methods, Access-Control-Allow-Origin set to * or the single Origin etc.). I have also tried running the script from disk (Origin null), webserver (Origin localhost:8888) and remote server (Origin standard url), because some browsers apparently block requests with local origin, but always the same negative result.

Any help how to get this working would be greatly appreciated.

like image 685
user3590656 Avatar asked Apr 30 '14 19:04

user3590656


2 Answers

I didn't use a directive, but I tried rawheader and it works.

code is as following:

 path("ping"){
   get{
     respondWithMediaType(`application/json`){
       respondWithHeader(RawHeader("Access-Control-Allow-Origin","*")){
         complete{
           jsonPrefix + """{"result": "PONG"}"""
         }
       }
     }
   }
 }
like image 57
Simon Avatar answered Nov 07 '22 12:11

Simon


If you have authorization in your API you must include the Authorization header in Access-Control-Allow-Headers.

The only way to test cors from cUrl is if you use the Origin header: curl cors

like image 30
Diego Alvarez Avatar answered Nov 07 '22 11:11

Diego Alvarez