解决跨域请求的filter

来源:互联网 发布:软件企业 编辑:程序博客网 时间:2024/06/05 08:57


@Componentpublic class SimpleCORSFilter implements Filter {  private final RedisTemplate<String, String> redisTemplate;  private final String key = "cors:prep:medical";  @Autowired  public SimpleCORSFilter(RedisTemplate<String, String> redisTemplate) {    this.redisTemplate = redisTemplate;    redisTemplate.opsForSet().add(key, "token");  }  public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {    HttpServletRequest request = ((HttpServletRequest) req);    HttpServletResponse response = (HttpServletResponse) res;    if (request.getMethod().equals("OPTIONS")) {      response.setHeader("Access-Control-Allow-Origin", "*");      response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");      response.setHeader("Access-Control-Max-Age", "0");      response.setHeader("Access-Control-Allow-Headers", StringUtils.join(redisTemplate.opsForSet().members(key), ','));      response.setStatus(200);      return;    } else {      response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));      Enumeration<String> headerNames = request.getHeaderNames();      while (headerNames.hasMoreElements()) {        redisTemplate.opsForSet().add(key, headerNames.nextElement());      }    }    chain.doFilter(req, res);  }  public void init(FilterConfig filterConfig) {  }  public void destroy() {  }}

由于“Content-type: text/html”不是一个简单的头,它会先向"http://bar.org/b"发出一个OPTIONS的HTTP请求。 回复可能包含这样的头:

Access-Control-Allow-Origin: http://foo.org

Access-Control-Max-Age: 3628800

Access-Control-Allow-Methods: GET,PUT, DELETE

Access-Control-Allow-Headers: content-type

"Access-Control-Allow-Origin"表明它允许"http://foo.org"发起跨域请求

"Access-Control-Max-Age"表明在3628800秒内,不需要再发送预检验请求,可以缓存该结果

"Access-Control-Allow-Methods"表明它允许GET、PUT、DELETE的外域请求

"Access-Control-Allow-Headers"表明它允许跨域请求包含content-type头

如果预检验请求获得通过,接下来Javascript就会发起真实的COR请求,过程跟简单的COR请求类似。