Cookie 跨域问题
HTTP 跨域响应头
指定了允许访问资源的外域地址; * 为通配符。 如果要跨域携带 cookie 则不能使用 通配符 后面说明原因
Access-Control-Allow-Origin : origin | *
允许跨域访问的请求方法
Access-Control-Allow-Methods : GET,POST ...
是否允许发送 cookie 如果需要响应时携带 cookie 必须设置该响应头为true
Access-Control-Allow-Credentials : true
允许携带的请求头
Access-Control-Allow-Headers : Origin,Content-Type,Accept,token,X-Requested-With ...
代码部分
Controller
@RestController
@RequestMapping("/info")
public class InfoController {
@RequestMapping("/cookie")
public void createCookie(HttpServletResponse response) {
Cookie cookie = new Cookie(UUID.randomUUID().toString(), UUID.randomUUID().toString());
//设置 cookie
response.addCookie(cookie);
}
@RequestMapping("/get/cookie")
public void getCookie(HttpServletRequest request) {
//读取 cookie1
for (Cookie cookie : request.getCookies())
System.out.println(cookie.getName() + "---" + cookie.getValue());
}
}
Filter(一般是在过滤器中设置好响应头)
@Configuration
@WebFilter("/**")
public class CrossDomainFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
//获取请求来源 一般跨域访问都会带有
String origin = req.getHeader("Origin");
if (origin != null && !"".equals(origin)) {
//允许该地址跨域访问
resp.addHeader("Access-Control-Allow-Origin", origin);
//跨域请求方式
resp.addHeader("Access-Control-Allow-Methods", "GET,POST");
//是否携带 cookie
resp.addHeader("Access-Control-Allow-Credentials", "true");
//允许携带请求头
resp.addHeader("Access-Control-Allow-Headers", "Origin,Content-Type,Accept,token,X-Requested-With");
}
chain.doFilter(request, response);
}
}
启动后进行访问
请求携带 cookie
以 XMLHttpRequest 为例子
需要设置 withCredentials 参数
let xhr = new XMLHttpRequest();
xhr.withCredentials = true;
前面说了 Access-Control-Allow-Origin 响应头 不能为 * (通配符) 的问题在这里 如果设置了 withCredentials=true 再进行跨域请求时浏览器则会抛出以下异常
Access to XMLHttpRequest at 'http://localhost:2333/ajax/info/cookie' from origin 'http://localhost:63342' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
处理好后在进行访问 /info/get/cookie 来打印 cookie
再写个 controller
@RestController
@RequestMapping("/read")
public class ReadController {
@RequestMapping("/cookie")
public void getCookie(HttpServletRequest request) {
//读取 cookie
for (Cookie cookie : request.getCookies())
System.out.println(cookie.getName() + "---" + cookie.getValue());
}
}
再访问 /read/cookie
发现读取不到保存的 cookie 原因在与 cookie 的路径问题 保存的 cookie 路径是在 /ajax/info 所以 request 才没有待上 cookie
解决方法为设置 cookie 的路径
@Value("${server.servlet.context-path}")
private String context;
@RequestMapping("/cookie")
public void createCookie(HttpServletResponse response) {
Cookie cookie = new Cookie(UUID.randomUUID().toString(), UUID.randomUUID().toString());
//设置路径
cookie.setPath(context);
//设置 cookie
response.addCookie(cookie);
}