文章目录
 - 1. 前置知识
 - 2. 原理和解决方案总结
 - 2.1. 跨域不通过原理流程图
 - 2.2. 实现原理:添加以下http响应头
 - 2.3. 四种跨域实现方式及优先级(从高到低)
 
 - 3. 具体实现代码
 - 3.1. 跨域全局配置方式-Filter(全适用)
 - 3.2. 跨域全局配置方式-SpringMvc
 - 3.3. 跨域单个配置方式-WebServlet
 - 3.4. 跨域单个配置方式-SpringMvc
 
 - 4.非java实现方式
 -  
 - 9. 参考文章
 
 
  
 
1. 前置知识
 
- 【尚硅谷】【视频】【B站】禹神:一小时彻底搞懂跨域&解决方案
 - 【尚硅谷】【笔记】【CSDN】禹神:彻底搞懂前端跨域&解决方案
 
 
2. 原理和解决方案总结
 
2.1. 跨域不通过原理流程图
 

 
2.2. 实现原理:添加以下http响应头
 
| 序号 | 响应头 | 含义 | 
|---|
| 1 | Access-Control-Allow-Origin | 允许的源 | 
| 2 | Access-Control-Allow-Methods | 允许的方法 | 
| 3 | Access-Control-Allow-Headers | 允许的自定义头 | 
| 4 | Access-Control-Max-Age | 预检请求的结果缓存时间(可选) | 
 

 
2.3. 四种跨域实现方式及优先级(从高到低)
 
- 跨域全局配置方式-Filter(全适用): 重写 Filter.doFilter(),设置 res.setHeader(“Access-Control-Allow-Origin”, “*”) 等响应头参数
 - 跨域全局配置方式-SpringMvc : 重写 WebMvcConfigurer.addCorsMappings(),设置 registry.addMapping(“/**”).allowedOrigins(“*”)等响应头参数(只对SpringMvc写法生效,对原生Servlet不生效)
 - 跨域单个配置方式-WebServlet: 设置 res.addHeader(“Access-Control-Allow-Origin”, “*”) 等响应头参数
 - 跨域单个配置方式-SpringMvc : 添加 @CrossOrigin注解,设置origins等响应头参数(只对SpringMvc写法生效,对原生Servlet不生效)
 
 
3. 具体实现代码
 
 
3.1. 跨域全局配置方式-Filter(全适用)
 
- 重写
Filter.doFilter(),设置 res.setHeader("Access-Control-Allow-Origin", "*") 等响应头参数 
 
@Configuration
public class CorsFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {HttpServletResponse res = (HttpServletResponse) response;res.setHeader("Access-Control-Allow-Origin", req.getHeader("Origin"));                                  if (req.getMethod().equalsIgnoreCase("OPTIONS") && !ObjUtil.hasNull(req.getHeader("Origin"), req.getHeader("Access-Control-Request-Method"))) {res.setHeader("Access-Control-Allow-Methods", req.getHeader("Access-Control-Request-Method"));      res.setHeader("Access-Control-Allow-Headers", req.getHeader("Access-Control-Request-Headers"));     res.setHeader("Access-Control-Max-Age", "5");                                                       return;}}
}
 
3.2. 跨域全局配置方式-SpringMvc
 
- 重写 WebMvcConfigurer.addCorsMappings(),设置 registry.addMapping(“/**”).allowedOrigins(“*”)等响应头参数(只对SpringMvc写法生效,对原生Servlet不生效)
 
 
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**")      .allowedOrigins("*")                    .allowedOriginPatterns("*")             .allowedMethods("*")                    .allowedHeaders("*")                    .maxAge(1800);                          }
}
 
3.3. 跨域单个配置方式-WebServlet
 
- 设置 res.addHeader(“Access-Control-Allow-Origin”, “*”) 等响应头参数
 
 
@Slf4j
@WebServlet(name = "ajax", value = {"/ajax/WebServlet", "/ajax/WebServlet/"})
public class AjaxWebServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse res) throws IOException {log.warn("method==【{}】, name==【{}】, header.origin==【{}】, Access-Control-Request-Method==【{}】, Access-Control-Request-Headers==【{}】", req.getMethod(), req.getParameter("name"), req.getHeader("Origin"), req.getHeader("Access-Control-Request-Method"), req.getHeader("Access-Control-Request-Headers"));res.setHeader("Access-Control-Allow-Origin", "*");      res.setHeader("Access-Control-Allow-Methods", "*");     res.setHeader("Access-Control-Allow-Headers", "*");     res.setHeader("Access-Control-Max-Age", "1800");        res.getWriter().write(DateUtil.now() + "@" + req.getMethod());}
}
 
3.4. 跨域单个配置方式-SpringMvc
 
- 添加 @CrossOrigin注解,设置origins等响应头参数(只对SpringMvc写法生效,对原生Servlet不生效)
 
 
@Slf4j
@RestController
@RequestMapping("/ajax")
public class AjaxController {@CrossOrigin(origins = {"*"},            originPatterns = {"*"},     methods = {},               allowedHeaders = {"*"},     maxAge = 1800               )@RequestMapping(value = "/CrossOrigin", method = {RequestMethod.GET, RequestMethod.PUT})@SneakyThrowsvoid ajax(HttpServletRequest req, HttpServletResponse res) {log.warn("method==【{}】, name==【{}】, header.origin==【{}】, Access-Control-Request-Method==【{}】, Access-Control-Request-Headers==【{}】", req.getMethod(), req.getParameter("name"), req.getHeader("Origin"), req.getHeader("Access-Control-Request-Method"), req.getHeader("Access-Control-Request-Headers"));res.getWriter().write(DateUtil.now() + "@" + req.getMethod());}
}
 
4.非java实现方式
 
4.1. nginx代理
 
 
- 配置nginx反向代理。在配置文件
nginx.conf的http中添加一个server - 将
AJAX请求通过nginx转发。本例中,将AJAX请求发给58080端口,然后转发给8080端口 
 
server {listen      58080;server_name localhost;location / {proxy_pass http://localhost:8080;# 增加响应头add_header       Access-Control-Allow-Origin  "*";          # 【跨域配置】[必需]               允许请求源  :默认值 无,配置"*"允许所有。if ($request_method = 'OPTIONS') {          # 如果是复杂请求的预检请求(参考SpringMvc,最好同时判断请求头Origin、Access-Control-Request-Method都不为null,略),设置以下响应头,且没必要透传,直接返回add_header   Access-Control-Allow-Origin  "*";          # 【跨域配置】[必需]               允许请求源  :默认值 无,配置"*"允许所有。add_header   Access-Control-Allow-Methods "*";          # 【跨域配置】[有复杂请求方法时必需]  允许请求方法:默认值 无,配置 "*",允许所有add_header   Access-Control-Allow-Headers "*";          # 【跨域配置】[有复杂请求头时必需]    允许请求头 : 默认值 无,配置 "*",允许所有add_header   Access-Control-Max-Age "5";                # 【跨域配置】[非必需]             预检缓存时长: 默认值 依赖客户端。EDGE浏览器默认值为3秒。【注意浏览器不要禁用缓存,否则不生效】return 204;}}
}
 
9. 参考文章
 
- @CrossOrigin详细参数说明
 - SpringBoot处理跨域请求的四种方法