应项目要求app端接口用Token,后台接口用Session造成的一系列跨域问题解决
1.web端开启cookie跨域分享后,SessionID每次请求都是变化的
解决方案:
Access-Control-Allow-Origin 跨域参数不能设置成通配符* 得根据实际取具体的内容
2.app端需要自定义header的token字段需要在
Access-Control-Allow-Headers 最后面补齐自己定义的token参数 如我的accessToken
此处给出我的代码
package com.thirtydays.common.interceptor; import java.io.IOException; import java.util.Arrays; import java.util.Enumeration; import java.util.List; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; /** * Cross-Origin Resource Sharing跨源资源共享 过滤器 允许前台页面通过ajax或者angualr直接访问 * */ @Component @Slf4j public class CorsFilter implements Filter { private static final Logger LOGGER = LoggerFactory.getLogger(CorsFilter.class); public static final String HOST_SPLIT_LINE = ","; public static final String ALLOW_HEADER_SPLIT_LINE = "\\|"; @Value("${page.home}") private String pageHome; @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse)res; HttpServletRequest request = (HttpServletRequest)req; List<String> domains = Arrays.asList(pageHome.split(HOST_SPLIT_LINE)); // 获取发起当前请求的域名 String originHead = request.getHeader("Origin"); int index = index(domains, originHead); if (index >= 0) { String matchHeader = domains.get(index); if (matchHeader.split(ALLOW_HEADER_SPLIT_LINE).length > 1) { String [] headerConfig = matchHeader.split(ALLOW_HEADER_SPLIT_LINE); // 允许的访问域,允许全部则为*,允许部分则配置详细的http地址,端口后不能有/ response.setHeader("Access-Control-Allow-Origin", headerConfig[1]); } else { response.setHeader("Access-Control-Allow-Origin", originHead); } } else { response.setHeader("Access-Control-Allow-Origin", domains.get(0)); } // 允许的访问域,允许全部则为*,允许部分则配置详细的http地址,端口后不能有/ // response.setHeader("Access-Control-Allow-Origin", "*"); // 访问授权有效期 为一周,单位为秒 response.setHeader("Access-Control-Max-Age", "604800"); // 默认只允许GET、POST请求,需要将PUT和DELETE也加入此列 response.setHeader("Access-Control-Allow-Methods", "OPTIONS,GET,POST,PUT,DELETE"); // 允许自定义 header accessToken response.setHeader("Access-Control-Allow-Headers", "Authorization,Origin, Accept, Content-Type, X-HTTP-Method, X-HTTP-METHOD-OVERRIDE,XRequestedWith,X-Requested-With,xhr,custom-enterpriseId,x-clientappversion, x-wxopenid, x-devicetype,accessToken"); response.setHeader("Access-Control-Allow-Credentials", "true"); chain.doFilter(req, res); } @Override public void destroy() { } /** * 计算Header所在索引位置 * @param domains 域名列表 * @param curDomain 当前页面域名 * @return * @return int 返回类型 * @date 2020年6月30日 上午11:53:31 */ private int index(List<String> domains, String curDomain) { String domain = null; for (int i = 0; i < domains.size(); i++) { domain = domains.get(i); String strs [] = domain.split(ALLOW_HEADER_SPLIT_LINE); if ((null != strs) && (strs[0].equals(curDomain))) { return i; } if (domain.equals(curDomain)) { return i; } } return -1; } }