背景
最近在基于大模型做一个前后端分离的小项目,主要是支持用户自定义自己的机器人。我是负责后端开发,使用SpringBoot
开发,前端是另外一个专门负责开发前端的大佬在开发。
这里就有一个问题,我后端接口的ip和端口与前端不同,也不可能相同,这就会形成跨域问题了。
什么是跨域呢?
跨域:协议,主机地址,端口,这三者有一个不同,都会形成跨域。
2. 解决跨域
2.1 SpringBoot中解决跨域
2.1.1 配置文件方式
配置文件中写入下面的代码:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
.allowCredentials(true)
.maxAge(3600)
.allowedHeaders("*");
}
}
其中allowedOrigins
设置允许哪些主机可以跨域访问
addMapping
设置访问哪些接口可以跨域
allowCredentials
设置是否可以跨域传递Cookie
2.1.2 拦截器方式
public class CrossInterceptorHandler implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
response.setHeader("Access-Control-Allow-Origin", "http://192.168.1.105");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "POST, GET , PUT , OPTIONS");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with,accept,authorization,content-type");
return true;
}
}
然后记得在配置文件中注入
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new CrossInterceptorHandler()).addPathPatterns("/**");
}
}
2.1.3 过滤器方式
import org.springframework.context.annotation.Configuration;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebFilter(filterName = "CorsFilter ")
@Configuration
public class CorsFilter implements Filter {
@Override
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-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, PATCH, DELETE, PUT");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
chain.doFilter(req, res);
}
}
2.1.4 注解方式
@CrossOrigin(origins = "http://192.168.105:8848")
这种方式颗粒度更细,可以控制到每个接口的访问,也可以在需要跨域访问的类上添加这个注解。
2.2 Nginx方式解决跨域
在nginx.conf
中配置反向代理,配置如下:
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name tosim.top;
location / {
root html/build;
try_files $uri /index.html; # try_files:检查文件; $uri:监测的文件路径; /index.html:文件不存在重定向的新路径
index index.html;
}
location /api/ {
# 把 /api 路径下的请求转发给真正的后端服务器
proxy_pass http://localhost:8080/;
# 把host头传过去,后端服务程序将收到your.domain.name, 否则收到的是localhost:18080
proxy_set_header Host $http_host;
# 把cookie中的path部分从/api替换成/service
proxy_cookie_path /api /;
# 把cookie的path部分从localhost:18080替换成your.domain.name
proxy_cookie_domain localhost:18080 tosim.top;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
3. 总结
这里列举了两大类解决前后端项目中的跨域问题,一种是在后端进行处理,另外一种是中间件进行处理。那么除了这两种方式,还有没有其它方式解决呢?比如在前端中解决跨域问题,也欢迎大家在评论区讨论。
更多内容,欢迎访问我的博客。
Q.E.D.