Cors解决跨域问题

当一个资源从与该资源本身所在的服务器不同的域或端口请求一个资源时,资源会发起一个跨域 HTTP 请求(下图来源网络)。出于安全性考虑,浏览器会限制或拦截跨域的请求,这样的场景非常多,同时也衍生了许多解决跨域的方法。例如我在http://localhost:8080上面的ajax请求http://localhost:9090上面的服务,报错如下

jquery.min.js:4 Failed to load http://localhost:9090/testJsonp?format=json: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8080' is therefore not allowed access.
本篇利用cors(跨域资源共享)技术来解决ajax跨域问题。cors是通过目标服务器返回的Header设置来控制是否可跨域。其中重要的一个参数即 Access-Control-Allow-Origin(访问控制允许来源),通过这个参数指定可以接收的请求资源。从实现上来说,用拦截器或过滤器均可。


使用示例



   corsFilter
   com.simonsfan.cn.filter.CorsFilter
   
      allowOrigin
      http://×××.com;
   
   
      allowMethods
      GET,POST,PUT,DELETE,OPTIONS
   
   
      allowCredentials
      true
   
   
      allowHeaders
      Content-Type
   


   corsFilter
   /*
     
如上在web.xml中定义了cors用到的一些常量,这些常量也可以直接定义为枚举或普通常量下面的CorsFilter类中

allowOrigin:允许来源(协议+域名+端口);

allowMethods:Http请求方法(get/post/put/delete/options);

allowCredentials:是否允许发送cookie及Http认证信息到服务端(true/false);

allowHeaders:目标服务器支持的头信息字段(Content-Type);
自定义过滤器CorsFilter类
public class CorsFilter implements Filter {
    private String allowOrigin;
    private String allowMethods;
    private String allowCredentials;
    private String allowHeaders;
    private String exposeHeaders;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        allowOrigin = filterConfig.getInitParameter("allowOrigin");
        allowMethods = filterConfig.getInitParameter("allowMethods");
        allowCredentials = filterConfig.getInitParameter("allowCredentials");
        allowHeaders = filterConfig.getInitParameter("allowHeaders");
        exposeHeaders = filterConfig.getInitParameter("exposeHeaders");
    }

    @Override
    public void destroy() {
    }

   @Override
   public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException,
         ServletException {
      HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        if (!StringUtils.isEmpty(allowOrigin)) {
            List allowOriginList = Arrays.asList(allowOrigin.split(","));
            if (!CollectionUtils.isEmpty(allowOriginList)) {
                String currentOrigin = request.getHeader("Origin");
                if (allowOriginList.contains(currentOrigin)) {
                    response.setHeader("Access-Control-Allow-Origin", currentOrigin);
                }
            }
        }
        if (!StringUtils.isEmpty(allowMethods)) {
            response.setHeader("Access-Control-Allow-Methods", allowMethods);
        }
        if (!StringUtils.isEmpty(allowCredentials)) {
            response.setHeader("Access-Control-Allow-Credentials", allowCredentials);//是否允许发送cookie和http认证信息到服务器
        }
        if (!StringUtils.isEmpty(allowHeaders)) {
            response.setHeader("Access-Control-Allow-Headers", allowHeaders);
        }
        if (!StringUtils.isEmpty(exposeHeaders)) {
            response.setHeader("Access-Control-Expose-Headers", exposeHeaders);
        }
        chain.doFilter(request, response);
   }
}
注意:如上代码是写在被调用方的服务中。

Cors对比jsonp

Cors可以实现和jsonp同样的效果,但是比jsonp强大些,它支持所有类型的http请求,而jsonp只支持get方式的请求。上述代码顺利解决ajax跨域问题。

你可能感兴趣的:(Java,Java编程之路)