OPTIONS request for restful cross-domain using CORS

北战南征 提交于 2019-12-18 08:48:06

问题


On client side I'm using Ajax.post (jquery 1.5) with json. On server side I'm using rest resteasy-jaxrs-2.0.1.GA. I found somewhere that i should add couple of headers to server response and I've done with following filter:

public void doFilter(   ServletRequest req,
                        ServletResponse res,
                        FilterChain filterChain)
    throws IOException, ServletException {

    MyServletRequestWrapper httpReq    = new MyServletRequestWrapper((HttpServletRequest)req);
    HttpServletResponse    httpRes   = (HttpServletResponse)res;

    HttpSession session = httpReq.getSession();


    httpRes.addHeader(ACCESS_CONTROL_ALLOW_ORIGIN, "*");
    httpRes.addHeader(ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");

   if (((HttpServletRequest) req).getMethod().equals("OPTIONS")){
        httpRes.addHeader(ACCESS_CONTROL_ALLOW_METHODS, "GET, POST, OPTIONS, PUT, DELETE");
        httpRes.addHeader(ACCESS_CONTROL_ALLOW_HEADERS, "content-type, x-requested-with, x-requested-by");
   }

  filterChain.doFilter(httpReq, httpRes);

}

It works fine cause to every single GET response above headers are added. Problem appears when I want to use POST request. When I use Ajax.post, at first server gets OPTIONS request and I've got following error:

Failed executing OPTIONS [REST_PATH] org.jboss.resteasy.spi.DefaultOptionsMethodException: No resource method found for options, return OK with Allow header

To solve above error I was trying to add method invoke with the same path as POST ([REST_PATH]) but with @OPTION annotation. In that case javac told me that symbol :class OPTIONS could not be found, even there is a OPTION.class in attached jaxrs library.

Any ideas to fix it? I would be very grateful for any clues.


回答1:


This question is quite old, but as a reference for others with similar problems - just recently i came across a nice "CORS Filter" you may want to consider using. It's just a matter of adding the following lines to your web.xml and it works like a charm.

<filter>
    <filter-name>CORS</filter-name>
    <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>CORS</filter-name>
    <servlet-name>MyServletNameGoesHere</servlet-name>
</filter-mapping>

and the maven dependency:

<dependency>
    <groupId>com.thetransactioncompany</groupId>
    <artifactId>cors-filter</artifactId>
    <version>1.5.1</version>
</dependency>



回答2:


When I was trying to call my service with an Angular 2 client RestEasy was responding to the preflight requests with the HTTP status 500 and the following error.

RESTEASY003655: No resource method found for options, return OK with Allow header

I tried RestEasy's CorsFilter but I'd like to propose a simple alternative. What if you don't want to write code handling the OPTIONS call for each of your endpoints ?

I implemented a simple filter that:

  1. Applies the CORS header you need to the response.
  2. Returns the HTTP status code 200 when calling an endpoint with the OPTIONS method. You tell the client that its CORS preflight requests were accepted.

Here is the code. Feel free to refine the filter if you only want to send back a 200 when querying a "real" endpoint.

@Provider 
public class CorsFilter implements ContainerResponseFilter {  

  @Override
  public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
    MultivaluedMap<String, Object> headers = responseContext.getHeaders();
    headers.add("Access-Control-Allow-Origin", "*"); // If you want to be more restrictive it could be localhost:4200
    headers.add("Access-Control-Allow-Methods", "GET, PUT, POST, OPTIONS"); // You can add HEAD, DELETE, TRACE, PATCH
    headers.add("Access-Control-Allow-Headers", "Content-Type, Authorization, Accept, Accept-Language"); // You can add many more

    if (requestContext.getMethod().equals("OPTIONS"))
        responseContext.setStatus(200);
}}

Make sure to understand CORS too.




回答3:


The CORS filter may be fine. I would like to point out as you wrote "To solve above error I was trying to add method invoke with the same path as POST ([REST_PATH]) but with @OPTION annotation. In that case javac told me that symbol :class OPTIONS could not be found, " that you had a typo there instead of @OPTIONS you wrote @OPTION without the S :)




回答4:


There is a built in CORS filter in tomcat. http://tomcat.apache.org/tomcat-7.0-doc/config/filter.html

<filter>
  <filter-name>CorsFilter</filter-name>
  <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>CorsFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>


来源:https://stackoverflow.com/questions/8077335/options-request-for-restful-cross-domain-using-cors

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!