springmvc解决跨域问题

第一种方法:

跨域实现类

[java]  view plain  copy
  1. package com.sq.filter;  
  2.   
  3. import org.springframework.stereotype.Component;  
  4.   
  5. import javax.servlet.*;  
  6. import javax.servlet.http.HttpServlet;  
  7. import javax.servlet.http.HttpServletResponse;  
  8. import java.io.IOException;  
  9.   
  10.   
  11. @Component  
  12. public class AccessFilter extends HttpServlet implements Filter {  
  13.   
  14.     private static final long serialVersionUID = 1L;  
  15.   
  16.   
  17.     @Override  
  18.     public void init(FilterConfig filterConfig) throws ServletException {  
  19.   
  20.     }  
  21.   
  22.     @Override  
  23.     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {  
  24.   
  25.         HttpServletResponse httpResponse = (HttpServletResponse) response;  
  26.         httpResponse.setHeader("Access-Control-Allow-Origin""*");  
  27.         httpResponse.setHeader("Access-Control-Allow-Methods""GET, POST, PUT, DELETE");  
  28.         httpResponse.setHeader("Access-Control-Max-Age""1800");  
  29.         httpResponse.setHeader("Access-Control-Allow-Headers""Origin, X-Requested-With, Content-Type, Accept");  
  30.         httpResponse.setHeader("Access-Control-Allow-Credentials""true");  
  31.         chain.doFilter(request, httpResponse);  
  32.     }  
  33. }  
web.xml配置
[html]  view plain  copy
  1. <filter>  
  2.          <filter-name>crosfilter-name>  
  3.          <filter-class>com.sq.filter.AccessFilterfilter-class>  
  4.      filter>  
  5.      <filter-mapping>  
  6.          <filter-name>crosfilter-name>  
  7.          <url-pattern>/*url-pattern>  
  8.      filter-mapping>  




第二种方法:

cros跨域配置

原创  2016年05月04日 14:00:49
  • 2646

前端应用为静态站点且部署在http://web.xxx.com域下,后端应用发布REST API并部署在http://api.xxx.com域下,如何使前端应用通过AJAX跨域访问后端应用呢?这需要使用到CORS技术来实现,这也是目前最好的解决方案了。

[CORS全称为Cross Origin Resource Sharing(跨域资源共享),服务端只需添加相关响应头信息,即可实现客户端发出AJAX跨域请求。]

CORS技术非常简单,易于实现,目前绝大多数浏览器均已支持该技术(IE8浏览器也支持了),服务端可通过任何编程语言来实现,只要能将CORS响应头写入response对象中即可。

下面我们继续扩展REST框架,通过CORS技术实现AJAX跨域访问。

首先,我们需要编写一个Filter,用于过滤所有的HTTP请求,并将CORS响应头写入response对象中,代码如下:

[java]  view plain copy
  1. public class CorsFilter implements Filter {  
  2.   
  3.     private String allowOrigin;  
  4.     private String allowMethods;  
  5.     private String allowCredentials;  
  6.     private String allowHeaders;  
  7.     private String exposeHeaders;  
  8.   
  9.     @Override  
  10.     public void init(FilterConfig filterConfig) throws ServletException {  
  11.         allowOrigin = filterConfig.getInitParameter("allowOrigin");  
  12.         allowMethods = filterConfig.getInitParameter("allowMethods");  
  13.         allowCredentials = filterConfig.getInitParameter("allowCredentials");  
  14.         allowHeaders = filterConfig.getInitParameter("allowHeaders");  
  15.         exposeHeaders = filterConfig.getInitParameter("exposeHeaders");  
  16.     }  
  17.   
  18.     @Override  
  19.     public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {  
  20.         HttpServletRequest request = (HttpServletRequest) req;  
  21.         HttpServletResponse response = (HttpServletResponse) res;  
  22.         if (StringUtil.isNotEmpty(allowOrigin)) {  
  23.             List allowOriginList = Arrays.asList(allowOrigin.split(","));  
  24.             if (CollectionUtil.isNotEmpty(allowOriginList)) {  
  25.                 String currentOrigin = request.getHeader("Origin");  
  26.                 if (allowOriginList.contains(currentOrigin)) {  
  27.                     response.setHeader("Access-Control-Allow-Origin", currentOrigin);  
  28.                 }  
  29.             }  
  30.         }  
  31.         if (StringUtil.isNotEmpty(allowMethods)) {  
  32.             response.setHeader("Access-Control-Allow-Methods", allowMethods);  
  33.         }  
  34.         if (StringUtil.isNotEmpty(allowCredentials)) {  
  35.             response.setHeader("Access-Control-Allow-Credentials", allowCredentials);  
  36.         }  
  37.         if (StringUtil.isNotEmpty(allowHeaders)) {  
  38.             response.setHeader("Access-Control-Allow-Headers", allowHeaders);  
  39.         }  
  40.         if (StringUtil.isNotEmpty(exposeHeaders)) {  
  41.             response.setHeader("Access-Control-Expose-Headers", exposeHeaders);  
  42.         }  
  43.         chain.doFilter(req, res);  
  44.     }  
  45.   
  46.     @Override  
  47.     public void destroy() {  
  48.     }  
  49. }  
以上CorsFilter将从web.xml中读取相关Filter初始化参数,并将在处理HTTP请求时将这些参数写入对应的CORS响应头中,下面大致描述一下这些CORS响应头的意义:

  • Access-Control-Allow-Origin:允许访问的客户端域名,例如:http://web.xxx.com,若为*,则表示从任意域都能访问,即不做任何限制。
  • Access-Control-Allow-Methods:允许访问的方法名,多个方法名用逗号分割,例如:GET,POST,PUT,DELETE,OPTIONS。
  • Access-Control-Allow-Credentials:是否允许请求带有验证信息,若要获取客户端域下的cookie时,需要将其设置为true。
  • Access-Control-Allow-Headers:允许服务端访问的客户端请求头,多个请求头用逗号分割,例如:Content-Type。
  • Access-Control-Expose-Headers:允许客户端访问的服务端响应头,多个响应头用逗号分割。

需要注意的是,CORS规范中定义Access-Control-Allow-Origin只允许两种取值,要么为*,要么为具体的域名,也就是说,不支持同时配置多个域名。为了解决跨多个域的问题,需要在代码中做一些处理,这里将Filter初始化参数作为一个域名的集合(用逗号分隔),只需从当前请求中获取Origin请求头,就知道是从哪个域中发出的请求,若该请求在以上允许的域名集合中,则将其放入Access-Control-Allow-Origin响应头,这样跨多个域的问题就轻松解决了。

以下是web.xml中配置CorsFilter的方法:

[xml]  view plain copy
  1. <filter>  
  2.     <filter-name>corsFilterfilter-name>  
  3.     <filter-class>com.xxx.api.cors.CorsFilterfilter-class>  
  4.     <init-param>  
  5.         <param-name>allowOriginparam-name>  
  6.         <param-value>http://web.xxx.comparam-value>  
  7.     init-param>  
  8.     <init-param>  
  9.         <param-name>allowMethodsparam-name>  
  10.         <param-value>GET,POST,PUT,DELETE,OPTIONSparam-value>  
  11.     init-param>  
  12.     <init-param>  
  13.         <param-name>allowCredentialsparam-name>  
  14.         <param-value>trueparam-value>  
  15.     init-param>  
  16.     <init-param>  
  17.         <param-name>allowHeadersparam-name>  
  18.         <param-value>Content-Typeparam-value>  
  19.     init-param>  
  20. filter>  
  21. <filter-mapping>  
  22.     <filter-name>corsFilterfilter-name>  
  23.     <url-pattern>/*url-pattern>  
  24. filter-mapping>  
完成以上过程即可实现AJAX跨域功能了,但似乎还存在另外一个问题,由于REST是无状态的,后端应用发布的REST API可在用户未登录的情况下被任意调用,这显然是不安全的,如何解决这个问题呢?我们需要为REST请求提供安全机制。

第三种方法:
   try {  
            HttpServletRequest httpRequest = (HttpServletRequest) request;  
            HttpServletResponse httpResponse = (HttpServletResponse) response;  
  
            // 跨域  
            String origin = httpRequest.getHeader("Origin");  
            if (origin == null) {  
                httpResponse.addHeader("Access-Control-Allow-Origin", "*");  
            } else {  
                httpResponse.addHeader("Access-Control-Allow-Origin", origin);  
            }  
            httpResponse.addHeader("Access-Control-Allow-Headers", "Origin, x-requested-with, Content-Type, Accept,X-Cookie");  
            httpResponse.addHeader("Access-Control-Allow-Credentials", "true");  
            httpResponse.addHeader("Access-Control-Allow-Methods", "GET,POST,PUT,OPTIONS,DELETE");  
            if ( httpRequest.getMethod().equals("OPTIONS") ) {  
                httpResponse.setStatus(HttpServletResponse.SC_OK);  
                return;  
            }  
            chain.doFilter(request, response);  
        } catch (Exception e) {  
            errorLogger.error("Exception in crossDomainFilter.doFilter", e);  
            throw e;  
        }  



第四种方法(不过没有经过实际验证):

spring mvc 支持options方法

原创  2016年01月20日 13:54:22
  • 4088

在web.xml中,添加

[html]  view plain  copy
  1. <init-param>  
  2.             <param-name>dispatchOptionsRequestparam-name>  
  3.             <param-value>trueparam-value>  
  4.         init-param>  

添加后

[html]  view plain  copy
  1. <servlet>  
  2.         <servlet-name>springdispatcherservlet-name>  
  3.         <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>  
  4.         <init-param>  
  5.             <param-name>contextConfigLocationparam-name>  
  6.             <param-value>classpath:springMvc-viewresolver.xmlparam-value>  
  7.         init-param>  
  8.         <init-param>  
  9.             <param-name>dispatchOptionsRequestparam-name>  
  10.             <param-value>trueparam-value>  
  11.         init-param>  
  12.         <load-on-startup>1load-on-startup>  
  13.     servlet>  

你可能感兴趣的:(工作)