一、什么是跨域问题
跨域问题通常指的是在浏览器中由于同源策略的限制而产生的问题。同源策略(Same-origin policy)是浏览器的一种安全措施,它要求请求的域名、协议和端口必须与提供资源的网站相同。当一个网页尝试访问另一个来源(即不同域名、协议或端口)的数据时,那么后端返回给浏览器的数据被浏览器拦截下来,这就是跨域。
二、跨域问题产生的原因
是因为浏览器的同源策略,同源策略(Same-origin policy)是浏览器的一项重要安全特性,用于控制不同来源的网页之间的交互。这项政策的主要目的是为了保护用户的隐私和数据安全,防止恶意网站执行某些恶意操作。
常见的跨域问题原因:
-
协议不同:如 https和http;
-
端口不同
-
域名不同
三、跨域问题的解决方法
1、使用@CrossOrigin注解(局部配置)
在方法上加上@CrossOrigin注解
@CrossOrigin(origins="*", allowedHeaders = "*"
methods = {RequestMethod.GET, RequestMethod.POST,
RequestMethod.PUT, RequestMethod.DELETE,RequestMethod.OPTIONS})
allowedHeaders = "*" 这段配置通常用于后端服务中,以确保客户端可以从不同的源发起请求,并且可以使用特定的HTTP头部。methods 指的是允许的请求方法
OPTIONS方法: 用于预检请求,检查服务器是否允许特定的跨域请求。
预检请求:CORS机制中的预检请求(Preflight Request)是浏览器为了确保跨域请求的安全性和兼容性而自动发送的一种特殊类型的HTTP请求。预检请求主要用于检查服务器是否允许特定类型的跨域请求。
2、全局配置
写一个配置类
@Configuration
public class CoreConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
// 配置跨域资源共享 (CORS)
registry.addMapping("/**") // 允许跨域访问的路径
.allowedOrigins("*") //允许所有来源
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")// 允许跨域访问的请求方法
.allowedHeaders("*")// 允许跨域访问的头部信息
.maxAge(3600)// 预检请求的有效期
.allowCredentials(true); // 允许携带cookie等验证信息
}
}
3、使用CorsFilter跨域
可以写一个请求过滤器,这段代码实现的是一个跨域资源共享(CORS, Cross-Origin Resource Sharing)过滤器。CORS 是一种机制,它使用额外的 HTTP 头来告诉浏览器允许一个域上的 web 应用程序访问来自另一个域的选定资源。
//@Component
public class CoreFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest hSRequest = (HttpServletRequest) request;
HttpServletResponse hSResponse = (HttpServletResponse) response;
//允许所有来源的跨域请求
hSResponse.setHeader("Access-Control-Allow-Origin", "*");
//指定允许的HTTP方法
hSResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
//预检请求的有效期为3600秒(1小时)
hSResponse.setHeader("Access-Control-Max-Age", "3600");
//列出服务器允许的HTTP头部信息
hSResponse.setHeader("Access-Control-Allow-Headers", "x-requested-with, authorization, content-type");
//指示是否支持用户凭证(如cookies、HTTP认证信息)
hSResponse.setHeader("Access-Control-Allow-Credentials", "true");
//检查请求的方法是否为 OPTIONS,是,则直接返回状态码200(SC_OK),
//不是 OPTIONS 请求,则继续过滤器链,让请求继续前进到下一个过滤器或目标资源。
if ("OPTIONS".equals(hSRequest.getMethod())) {
hSResponse.setStatus(HttpServletResponse.SC_OK);
} else {
filterChain.doFilter(request, response);
}
}
}
4、使用Node代理
Node代理 是指用 Node 服务器代理客户端和目标服务器之间的网络请求。同源策略是浏览器需要遵循的标准,服务器与服务器之间没有同源策略,Node 代理服务器监听客户端请求,转发给目标服务器,再接收响应发给客户端。
只需在vite.config文件里配置即可
server: {
proxy: {
'/api': { //所有以 /api 开头的请求
target: 'http://localhost:8080',//目标服务器地址
changeOrigin: true,//允许代理服务器修改请求的源
}
}
}
5、使用Nginx来实现跨域
在default.config文件里配置
location /api {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'POST,GET,OPTIONS';
//OPTIONS方法通常用于预检请求(Preflight Requests),这是一种特殊的请求,用于检查服务器是否支持跨域请求及其相关参数。
}
我们在打包前端项目的啥时候加入一个nginx的配置文件
upstream wms-app {
server 192.168.21.92:8080;
server 192.168.21.92:8081;
}
server {
listen 80;
listen [::]:80;
server_name localhost;
access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html; #解决单页面找不到路径问题 404
}
location /api {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'POST,GET,OPTIONS';
proxy_pass http://wms-app ; #可以配置多个下游服务,具有负载功能
#proxy_pass http://192.168.14.3:3666; #仅配置一个下游服务,不具有负载均衡能力
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}