前后端分离跨域问题解决
背景:前端Vue集成到App内部,使用file协议在WebView中加载,使用axios请求数据,JsBridge和原生互动,中间使用 Nginx 负载代理 ,后端是 SpringBoot
跨域遇到的问题:
1. 简单请求、复杂请求
2. iOS 中 WKWebVIew 问题
需要在info.plist 中开启 NSAppTransportSecurity --> NSAllowsArbitraryLoads = True
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict> </dict> </plist>
跨域方式有两种(不能同时启用)
Springboot配置跨域 (推荐)
Springboot 配置跨域的方式有多种:自定义Filter 、SpringMvc内置的CorsFilter、注解(@CrossOrigin)等,我用 SpringMvc内置的CorsFilter 的方式配置(该方式忘记抄的哪个大佬的了😭😭)
import org.springframework.context.annotation.*; import org.springframework.web.cors.*; import org.springframework.web.filter.*; /** * 跨域配置 */ @Configuration public class CorsConfig { // 当前跨域请求最大有效时长。这里默认30天 private final long MAX_AGE = 30 * 24 * 3600; private CorsConfiguration initCorsConf() { CorsConfiguration corsConf = new CorsConfiguration(); corsConf.addAllowedOrigin("*"); // 访问源地址,* 允许所有 corsConf.addAllowedHeader("*"); // 访问源请求头,* 允许所有 corsConf.addAllowedMethod("*"); // 访问源请求方法,* 允许所有 corsConf.setMaxAge(MAX_AGE); return corsConf; } @Bean public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", initCorsConf()); // 匹配所有的 action return new CorsFilter(source); } }
⚠️注意 Springboot配置了跨域后Nginx就不要配置跨域了,双重配置axios校验 origin 不通过,此时Nginx就是代理负载功能
http { ... upstream testServer { server 127.0.0.1:8000; } server { listen 80; location /test/ { # 只做代理负载用 proxy_pass http://testServer/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; ... } } ... }
Nginx配置跨域
http { ... upstream testServer { server 127.0.0.1:8000; } server { listen 80; location /test/ { add_header Access-Control-Allow-Credentials true always; add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS always; add_header Access-Control-Allow-Headers $http_access_control_request_headers; add_header Access-Control-Max-Age 3600; # 如果后端服务里已经配置了跨域,以下两条配置 一定要 注释掉 add_header Access-Control-Allow-Origin $http_origin always; if ($request_method = OPTIONS) { # 复杂请求会在请求前先开启一个 OPTIONS 请求,直接返回 200 return 200; } proxy_pass http://testServer/; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; ... } } ... }