跨域处理
产生原因
跨域产生的原因是由于前端地址与后台接口不是同源,从而导致异步请求发送失败
非同源产生的问题
- Cookie、LocalStorage 和 IndexDB 无法获取
- DOM 无法获得
- AJAX 请求不能发送
同源条件
协议,端口,主机 三者相同即为同源。反之,其中只要 某一个 不一样则为不同源
解决方案
本地开发跨域
本地开发一般使用下面 3 种方式进行处理
- vite 的 proxy 进行代理
- 后台开启 cors
- 使用 nginx 转发请求
生产环境跨域
生产环境一般使用下面 2 种方式进行处理
- 后台开启 cors
- 使用 nginx 转发请求
后台开启 cors 不需要前端做任何改动
后台开启cors
java
@Bean
public CorsFilter corsFilter() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final org.springframework.web.cors.CorsConfiguration config = new org.springframework.web.cors.CorsConfiguration();
// 允许cookies跨域
config.setAllowCredentials(true);
// #允许向该服务器提交请求的URI,*表示全部允许,在SpringMVC中,如果设成*,会自动转成当前请求头中的Origin
config.addAllowedOriginPattern("*");
// #允许访问的头信息,*表示全部
config.addAllowedHeader("*");
// 预检请求的缓存时间(秒),即在这个时间段里,对于相同的跨域请求不会再预检了
config.setMaxAge(18000L);
// 允许提交请求的方法,*表示全部允许
config.addAllowedMethod("OPTIONS");
config.addAllowedMethod("HEAD");
// 允许Get的请求类型
config.addAllowedMethod("GET");
config.addAllowedMethod("PUT");
config.addAllowedMethod("POST");
config.addAllowedMethod("DELETE");
config.addAllowedMethod("PATCH");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
java
/**
* 跨域过滤器
*/
@Component
@Order(-200)
public class CorsFilter implements Filter {
static final String OPTIONS = "OPTIONS";
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
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");
// 允许的header参数
response.setHeader("Access-Control-Allow-Headers", "x-requested-with,satoken");
// 如果是预检请求,直接返回
if (OPTIONS.equals(request.getMethod())) {
System.out.println("=======================浏览器发来了OPTIONS预检请求==========");
response.getWriter().print("");
return;
}
// System.out.println("*********************************过滤器被使用**************************");
chain.doFilter(req, res);
}
@Override
public void init(FilterConfig filterConfig) {
}
@Override
public void destroy() {
}
}
使用Nginx转发请求
配置前端项目接口地址
java
# 在.env.production内,配置接口地址
VITE_GLOB_API_URL=/api
在nginx配置请求转发到后台
java
server {
listen 80;
server_name tangyh.top;
# 接口代理,用于解决跨域问题
location /api {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# 后台 lamp-gateway-server 接口地址
proxy_pass http://110.110.1.1:8760/api;
proxy_redirect default;
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
}
}