java spring 跨域

在过滤器里面添加头就可以了,但是会碰到下面的问题:
. A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true. Origin 'http://localhost' is therefore not allowed access. The credentials mode of an XMLHttpRequest is controlled by the withCredentials attribute.
当前端请求有参数:
withCredentials: true的时候会出现上述问题,因为浏览器的安全策略,当允许 credentials 的时候,Access-Control-Allow-Origin 值不能是*,而必须是一个指定的域名, 那么如何针对不同的访问设定对应的跨源允许域呢?

HTTP 中的Referer能很好地实现该需求,当在一个域下发起一个 CORS 请求时,HTTP 请求头的 Referer 值会自动被设置为当前页面域,此时只要在服务器端读取 Referer 值,构造出相应的 Access-Control-Allow-Origin 值即可,参考下面代码

 public void doFilter(ServletRequest request, ServletResponse response,
      FilterChain chain) throws IOException, ServletException {
    HttpServletRequest req = (HttpServletRequest) request;
    String referer = req.getHeader("referer");
    HttpServletResponse res = (HttpServletResponse) response;
    if (!StringUtils.isEmpty(referer)) {
      try {
        res.setHeader("Access-Control-Allow-Origin", getHost(referer));
      } catch (Exception e) {
        log.error(e.getMessage(), e);
        res.setHeader("Access-Control-Allow-Origin", "*");
      }
    } else {
      res.setHeader("Access-Control-Allow-Origin", "*");
    }
    res.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
    res.setHeader("Access-Control-Max-Age", "3600");
    res.setHeader("Access-Control-Allow-Headers", "Content-Type, token, nonce, signature, uid");

    HttpServletRequest httpServletRequest = (HttpServletRequest) request;
    // 防止流读取一次后就没有了, 所以需要将流继续写出去
    ServletRequest requestWrapper = new BodyReaderHttpServletRequestWrapper(httpServletRequest);
    chain.doFilter(requestWrapper, response);
  }

  private String getHost(String referer) {
    String split = "/";
    String[] ss = referer.split(split);
    return ss[0] + split + ss[1] + split + ss[2];
  }

你可能感兴趣的:(java spring 跨域)