OPTIONS使用CORS请求restful跨域

时间:2011-11-10 09:25:27

标签: rest xmlhttprequest http-options-method

在客户端,我正在使用带有json的Ajax.post(jquery 1.5)。在服务器端我使用rest resteasy-jaxrs-2.0.1.GA。我找到了一个地方,我应该在服务器响应中添加几个标题,并且我已经完成了以下过滤器:

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);

}

它工作得很好,因为添加了上面标题的每个GET响应。当我想使用POST请求时出现问题。当我使用Ajax.post时,在第一个服务器获取OPTIONS请求并且我有以下错误:

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

为了解决上述错误,我尝试使用与POST([REST_PATH])相同的路径添加方法调用,但使用@OPTION注释。在那种情况下,javac告诉我符号:类OPTIONS无法找到,即使附加的jaxrs库中有一个OPTION.class。

有什么想法来解决它吗?我会非常感谢任何线索。

4 个答案:

答案 0 :(得分:1)

这个问题已经很老了,但作为其他有类似问题的人的参考 - 最近我遇到了一个很好的“CORS过滤器”你可能要考虑使用。只需在web.xml中添加以下行,它就像魅力一样。

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

和maven依赖:

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

答案 1 :(得分:1)

当我尝试使用Angular 2客户端调用我的服务时,RestEasy正在响应HTTP状态为500的预检请求以及以下错误。

  

RESTEASY003655:找不到选项的资源方法,返回OK   允许标题

我试过RestEasy's CorsFilter,但我想提出一个简单的替代方案。如果您不想为每个端点编写处理OPTIONS调用的代码,该怎么办?

我实现了一个简单的过滤器:

  1. 将响应所需的CORS标头应用于此。
  2. 使用OPTIONS方法调用端点时返回HTTP状态代码200。您告诉客户端其CORS预检请求已被接受。
  3. 这是代码。如果您只想在查询“真实”端点时发回200,请随意优化过滤器。

    @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);
    }}
    

    请务必understand CORS

答案 2 :(得分:0)

CORS过滤器可能没问题。我想指出,当你写道“为了解决上面的错误,我试图用与POST([REST_PATH]相同的路径)添加方法调用但是使用@OPTION注释。在这种情况下,javac告诉我符号:class OPTIONS can没有找到,“你有一个拼写错误,而不是@OPTIONS你没有@OPTION写的S:)

答案 3 :(得分:0)

tomcat中有一个内置的CORS过滤器。 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>