4

I am in the context of a Rest API. As I am performing cross domain request, I need to send back the header "Access-Control-Allow-Origin".

I have a controller such:

@Controller
@RequestMapping("/api")
public class PackageManagerRestController {


    @RequestMapping(method = RequestMethod.OPTIONS, value = "/test")
    public void commonOptions(HttpServletResponse theHttpServletResponse) throws IOException {
        theHttpServletResponse.addHeader("Access-Control-Allow-Headers", "origin, content-type, accept, x-requested-with");
        theHttpServletResponse.addHeader("Access-Control-Max-Age", "60"); // seconds to cache preflight request --> less OPTIONS traffic
        theHttpServletResponse.addHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
        theHttpServletResponse.addHeader("Access-Control-Allow-Origin", "*");
    }

    @RequestMapping(method = RequestMethod.GET, value = "/test")
    public void getPtions(HttpServletResponse theHttpServletResponse) throws IOException {
        theHttpServletResponse.addHeader("Access-Control-Allow-Headers", "origin, content-type, accept, x-requested-with");
        theHttpServletResponse.addHeader("Access-Control-Max-Age", "60"); // seconds to cache preflight request --> less OPTIONS traffic
        theHttpServletResponse.addHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
        theHttpServletResponse.addHeader("Access-Control-Allow-Origin", "*");
    }
}

If I run a test with GET, the result is as expected:

$ curl -i -X GET http://localhost:8081/api/test
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Access-Control-Allow-Headers: origin, content-type, accept, x-requested-with
Access-Control-Max-Age: 60
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Origin: *
Content-Length: 0
Date: Wed, 16 Apr 2014 08:18:38 GMT

However, if I send the request with OPTIONS, the controller never handles the request:

$ curl -i -X OPTIONS http://localhost:8081/api/test
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Allow: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
Content-Length: 0
Date: Wed, 16 Apr 2014 08:19:56 GMT

Anyone has any clue of why I am receiving this "default response" and why I cannot customize it ?

Jonik
  • 80,077
  • 70
  • 264
  • 372
Tk421
  • 6,196
  • 6
  • 38
  • 47
  • Are you using Spring Security in your project? If so, as far as I know, Spring Security does allow you to make cross domain GET requests only and blocks other HTTP method types in its default configuration. – emre Apr 16 '14 at 08:35
  • 2
    For default Spring DispatcherServlet supports GET, HEAD, POST, PUT, PATCH and DELETE only; if you want to support TRACE and OPTIONS you have to put "dispatchOptionsRequest" and "dispatchTraceRequest" properties to "true"; check here http://docs.spring.io/spring/docs/4.0.3.RELEASE/javadoc-api/ – Angelo Immediata Apr 16 '14 at 08:40
  • Closely related: http://stackoverflow.com/questions/9521690/how-to-handle-http-options-with-spring-mvc – Jonik Oct 25 '15 at 22:03

2 Answers2

3

For default Spring DispatcherServlet supports GET, HEAD, POST, PUT, PATCH and DELETE only; if you want to support TRACE and OPTIONS you have to put "dispatchOptionsRequest" and "dispatchTraceRequest" properties to "true"; check here docs.spring.io/spring/docs/4.0.3.RELEASE/javadoc-api

In order to support OPTIONS too in your web.xml you have to put this:

<init-param>
<param-name>dispatchOptionsRequest</param-name>
<param-value>true</param-value>
</init-param>

By adding it I can handle OPTIONS:

~$ curl -i -X OPTIONS http://localhost:8180/sample/api/test
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Access-Control-Allow-Headers: origin, content-type, accept, x-requested-with
Access-Control-Max-Age: 60
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Origin: *
Allow: GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
Content-Length: 0
Date: Wed, 16 Apr 2014 08:44:55 GMT

Angelo

Angelo Immediata
  • 6,635
  • 4
  • 33
  • 65
  • 1
    How could I do this without using a web.xml? – daniegarcia254 Jun 08 '16 at 22:46
  • @daniegarcia254: By starting from spring 3.2 in a servlet 3 environment, there is a variety of DispatcherServlet initializer; you can use, for example, AbstractAnnotationConfigDispatcherServletInitializer and you can add this code to enable dispatchOptionsRequest: `protected void customizeRegistration(Dynamic registration) {registration.setInitParameter("dispatchOptionsRequest", "true");}` – Angelo Immediata Jun 09 '16 at 08:52
  • 1
    I've applied your idea, still not working. Could you check my question please? http://stackoverflow.com/questions/37733501/enable-cors-for-options-request-using-spring-framework – daniegarcia254 Jun 09 '16 at 18:23
2

according to the last answer I resolve my problem

@RequestMapping(value = "/**",method = RequestMethod.OPTIONS)
public String getOption(HttpServletResponse response,Model model)
{
    response.setHeader("Access-Control-Allow-Origin","*");

    response.setHeader("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE");

    return "";
}

and we need to add something to the dispacherservlet

<init-param>
        <param-name>dispatchOptionsRequest</param-name>
        <param-value>true</param-value>
    </init-param>

and this is over

SunkSky
  • 85
  • 7