Springboot跨域处理
1. 为什么出现跨域
浏览器同源策略限制。 同源策略(Same Origin Policy): 是一种约束;浏览器最核心也是最基础的安全功能。缺少了同源策略,浏览器正常功能都可能受影响。 同源策略阻止一个域的javaScript脚本和另一个域的内进行交互。所谓同源就是两个页面具有相同的协议(protocol)、主机(host)和端口号(port)。
非同源限制: 【1】无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB 【2】无法接触非同源网页的 DOM 【3】无法向非同源地址发送 AJAX 请求
Java 后端实现CORS跨域请求:
- 返回新的CorsFilter
- 重写 WebMvcConfigurer
- 使用注解 @CrossOrigin
- 手动设置响应头 (HttpServletResponse)
- 自定web filter 实现跨域
2.跨域处理
# 1.返回新的CorsFilter(全局跨域)@Configurationpublic class GlobalCorsConfig {@Beanpublic CorsFilter corsFilter() {//1. 添加 CORS配置信息CorsConfiguration config = new CorsConfiguration();//放行哪些原始域config.addAllowedOrigin("*");//是否发送 Cookieconfig.setAllowCredentials(true);//放行哪些请求方式config.addAllowedMethod("*");//放行哪些原始请求头部信息config.addAllowedHeader("*");//暴露哪些头部信息config.addExposedHeader("*");//2. 添加映射路径UrlBasedCorsConfigurationSource corsConfigurationSource = new UrlBasedCorsConfigurationSource();corsConfigurationSource.registerCorsConfiguration("/**",config);//3. 返回新的CorsFilterreturn new CorsFilter(corsConfigurationSource);}}
# 2.重写WebMvcConfigurer(全局跨域)@Configurationpublic class CorsConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**")//是否发送Cookie.allowCredentials(true)//放行哪些原始域.allowedOrigins("*").allowedMethods(new String[]{"GET", "POST", "PUT", "DELETE"}).allowedHeaders("*").exposedHeaders("*");}}
# 3.使用注解 --在类上使用,允许类下方法跨域@RestController@CrossOrigin(origins = "*")public class HelloController {@RequestMapping("/hello")public String hello() {return "hello world";}}
# 4.编写一个过滤器,起名叫MyCorsFilter.javaimport java.io.IOException;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.HttpServletResponse;import org.springframework.stereotype.Component;@Componentpublic class MyCorsFilter implements Filter {public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {HttpServletResponse response = (HttpServletResponse) res;response.setHeader("Access-Control-Allow-Origin", "*");response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");response.setHeader("Access-Control-Max-Age", "3600");response.setHeader("Access-Control-Allow-Headers", "x-requested-with,content-type");chain.doFilter(req, res);}public void init(FilterConfig filterConfig) {}public void destroy() {}}
<!-- web.xml中配置跨域访问 --><filter><filter-name>CorsFilter</filter-name><filter-class>com.mesnac.aop.MyCorsFilter</filter-class></filter><filter-mapping><filter-name>CorsFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>
5. 前端使用jsonp进行跨域:
# 在nginx/conf/ 目录下,新增enable-cors.conf文件# allow origin listset $ACAO '*';# set single originif ($http_origin ~* (www.helloworld.com)$) { #网站域名set $ACAO $http_origin;}if ($cors = "trueget") {add_header 'Access-Control-Allow-Origin' "$http_origin";add_header 'Access-Control-Allow-Credentials' 'true';add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';}if ($request_method = 'OPTIONS') {set $cors "${cors}options";}if ($request_method = 'GET') {set $cors "${cors}get";}if ($request_method = 'POST') {set $cors "${cors}post";}
<!-- 在nginx.conf文件中添加配置 -->upstream front_server{server www.helloworld.com:9000;}upstream api_server{server www.helloworld.com:8080;}server {listen 80;server_name www.helloworld.com;location ~ ^/api/ { <!--后端的映射-->include enable-cors.conf; <!--引入新增的配置信息-->proxy_pass http://api_server;rewrite "^/api/(.*)$" /$1 break;}location ~ ^/ {proxy_pass http://front_server;}}
