Java Web应用程序上的CORS问题 [英] CORS issue on java web application

查看:95
本文介绍了Java Web应用程序上的CORS问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

后端是由Spring MVC开发的,并托管在tomcat中。

The backend is developed by Spring MVC and hosted in tomcat.

当我在Chrome中使用邮递员开发工具测试端点(Restful)时,一切正常。服务器中已成功添加 Access-Control-Allow-Origin, *。就像下面的截图一样

When I use postman dev tool in Chrome to test the endpoint (Restful), everything is working fine. The "Access-Control-Allow-Origin", "*" is successfully added in the server. like below screenshot

但是当我编写Ajax进行相同的请求时。由于浏览器具有原始策略(邮递员没有此策略),因此它将首先向服务器发送HTTP OPTIONS请求标头,以确定实际请求是否可以安全发送。如下面的截图。

But when I wrote the Ajax to make the same request. Because browser has the Origin Policy (postman has no this policy), it will first send an HTTP OPTIONS request header to the server to determine whether the actual request is safe to send. like below screenshot.

响应标头与我从邮递员那里获得的标头完全不同,并且没有标头中的Access-Control-Allow-Origin, *。我认为服务器只是不能接受选项请求。

The response header is quite different to the one I got from postman, and there is no "Access-Control-Allow-Origin", "*" in the header. I think the server just can't accept the options request.

我试图通过以下链接在tomcat web.xml中添加过滤器: http://enable-cors.org/server_tomcat.html

I have tried to add the filter in tomcat web.xml by looking this link: http://enable-cors.org/server_tomcat.html

仅使用不带Origin策略的curl和postman等开发工具才能完美工作。但这在Ajax的浏览器上不起作用。

It's Only working perfectly by using dev tool like curl and postman which has no Origin policy. But it's not working on the browser by Ajax.

请参见下面的过滤器类

public class SimpleCORSFilter implements Filter {
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
System.out.println("test123");
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
        chain.doFilter(req, res);
    }
    public void init(FilterConfig filterConfig) {}
    public void destroy() {}
}

在使用邮递员或curl时,我在过滤器中使用 System.out.println( test123); 它在控制台中打印了 test123,但是在使用浏览器时却没有打印,所以我猜浏览器发送了OPTIONS请求,并且过滤器没有拦截它,或者其他东西首先拦截了浏览器的请求?

I use the System.out.println("test123"); in the filter, when using postman or curl, it printed the 'test123' in the console, but didn't print when using browser, so I guess the browser send the OPTIONS request, and the filter didn't intercept it, or other things intercept the request from browser first?

有人可以帮助我吗?谢谢。

Can anyone help me please? Thanks.

推荐答案

如果您使用的是tomcat,则可以使用 tomcat的实现在您的web.xml中:

If you are using tomcat you can have tomcat's implementaion in your web.xml:

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

或者在我的应用程序中,我做了一个过滤器(已更新),如下所示:

Or In my application I did a filter(updated) like below:

public class CorsFilter implements Filter {


    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, HEAD, OPTIONS");
        response.setHeader("Access-Control-Allow-Headers", "Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
      if ("OPTIONS".equalsIgnoreCase((HttpServletRequest) servletRequest.getMethod())) {
        response.setStatus(HttpServletResponse.SC_OK);
      } else {
         filterChain.doFilter(servletRequest, response);
      }

    }

    @Override
    public void destroy() {

    }
}

另外请注意,您不应使用 @Component

Also please note that you should not annotate filter class with Spring's annotations like @Component

或者更好的选择是 Spring对CORS的支持

Or better you can go with Spring's CORS support

这篇关于Java Web应用程序上的CORS问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆