前后端分离解决跨域问题,偶然的相遇——options请求–即预检请求
前端
后端
此处配置的是过滤器
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebFilter(urlPatterns = "/*", filterName = "HeaderFilter")
public class HeaderFilter implements Filter {
Logger logger = LoggerFactory.getLogger(HeaderFilter.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// System.out.println("filter......init");
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
// System.out.println("filter......dofilter");
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));//解决跨域访问报错,这里不能使用*
response.setHeader("Access-Control-Allow-Credentials", "true"); //是否支持cookie跨域
response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600"); //设置过期时间
response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With,Access-Control-Allow-Origin, Content-Type, Accept, client_id, uuid, Authorization,sign");//支持的请求头
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // 支持HTTP 1.1.
response.setHeader("Pragma", "no-cache"); // 支持HTTP 1.0. response.setHeader("Expires", "0");
System.out.println(request.getMethod());
if ("OPTIONS".equals(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
return;
}
chain.doFilter(request, resp);
}
@Override
public void destroy() {
// System.out.println("filter......destroy");
}
}
这里面值得注意的是: 偶然的相遇——options请求–即预检请求
在使用ajax发送异步请求的时候,这里谷歌浏览器会发送两次请求。(一次预请求,一次正式的请求)此时如果预请求不能通过的话,宏观上看,会阻塞后面的请求。
解决方法就是:在过滤器中配置
if ("OPTIONS".equals(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
return;
}
如果预请求进来的话,返回一个正常的状态