什么是跨域?
- 浏览器为了用户的安全, 仅允许向同域名、同端口的服务器发送请求.
- 比如:前端的域名是user, 后端域名是user-backend, 域名不一样就出现了跨域, 跨域的话就报错了
预检请求
- 为了防止跨域, 或者说为了检测跨域, 浏览器它会在发送正式请求之前, 发送一个预检请求, 预检的请求方法是OPTIONS
- 预检请求经常用来检查是否跨域, 或者换一句话说, 当我们请求的域名是和当前网页域名不同的时候, 就会发送预检请求
- 预检请求的作用: 就是提前探路, 如果有问题, 那也不用发下一个请求了, 或者说下一个请求直接拒绝掉
如何解决跨域
-
把域名和端口改成相同的(不常用)
- 在前后端分离的情况下, 域名和端口基本上无法同步, 所以不常用
-
网关支持(nginx)
- 在nginx的配置文件中加入以下内容
location ^~ /api/ { proxy_pass http://127.0.0.1:8080/api/; 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 '*'; if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Allow-Origin' $http_origin; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range'; add_header 'Access-Control-Max-Age' 1728000; add_header 'Content-Type' 'text/plain; charset=utf-8'; add_header 'Content-Length' 0; return 204; } }
-
修改后端服务
-
(1) 在代码中添加@CrossOrigin注解, 用于处理跨域请求, 它允许来自”http://xxx.com”的请求访问资源, 并允许携带凭证(如cookies)
-
((2) 添加web全局清求拦截器(常用)
-
(3) 返回新的CorsFilter
@Configuration public class CorsConfig { private CorsConfiguration buildConfig() { CorsConfiguration corsConfiguration = new CorsConfiguration(); corsConfiguration.addAllowedOrigin("*"); corsConfiguration.addAllowedHeader("*"); corsConfiguration.addAllowedMethod("*"); corsConfiguration.setMaxAge(3600L); corsConfiguration.setAllowCredentials(true); return corsConfiguration; } @Bean public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", buildConfig()); return new CorsFilter(source); } }
- (4) 手工设置响应头(HttpServletResponse)
@RequestMapping("/test") @ResponseBody public String test(){ response.addHeader("Access-Control-Allow-Origin", "http://localhost:8080"); return "success"; }
-