在若依(RuoYi)框架中,跨域请求是一个常见的需求。特别是在前后端分离的架构下,前端页面和后端API通常部署在不同的域名或端口上,这就需要解决跨域问题。本文将详细探讨如何在若依框架中实现跨域请求的处理方案。
跨域问题源于浏览器的同源策略(Same-Origin Policy),它限制了从一个源加载的文档或脚本如何与来自另一个源的资源进行交互。所谓同源是指协议、域名和端口号都相同。如果存在不同,则会触发跨域限制。
例如:
http://localhost:8080
http://localhost:8081
由于端口号不同,因此被视为跨域。
若依框架基于Spring Boot构建,而Spring Boot提供了非常便捷的跨域配置方式。以下是几种常用的实现方法:
通过实现WebMvcConfigurer
接口,并重写addCorsMappings
方法,可以为整个项目设置跨域规则。
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // 允许所有路径跨域
.allowedOrigins("*") // 允许所有来源
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 允许的HTTP方法
.allowedHeaders("*") // 允许的头部信息
.allowCredentials(true); // 是否允许携带Cookie
}
}
注意:生产环境中尽量避免使用*
作为allowedOrigins
,应明确指定允许的域名以提高安全性。
对于特定的Controller或方法,可以直接使用@CrossOrigin
注解来实现跨域。
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@CrossOrigin(origins = "http://localhost:8080") // 指定允许的来源
public class TestController {
@GetMapping("/test")
public String test() {
return "跨域测试成功!";
}
}
这种方式适合对单个接口或控制器进行跨域配置。
除了直接在后端代码中处理跨域问题外,还可以通过Nginx代理的方式解决跨域。具体步骤如下:
假设前端运行在http://localhost:8080
,后端运行在http://localhost:8081
,可以通过Nginx将前端请求转发到后端。
server {
listen 80;
server_name localhost;
location /api/ {
proxy_pass http://localhost:8081/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location / {
root /path/to/frontend/dist; # 前端静态文件路径
index index.html;
}
}
在这种方式下,前端请求http://localhost/api/test
会被Nginx转发到http://localhost:8081/test
,从而避免了跨域问题。
如果需要更灵活的跨域控制,可以自定义一个过滤器,在请求到达Controller之前处理跨域相关逻辑。
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
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-Methods", "GET, POST, PUT, DELETE, OPTIONS");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
response.setHeader("Access-Control-Allow-Credentials", "true");
if ("OPTIONS".equalsIgnoreCase(((javax.servlet.http.HttpServletRequest) req).getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, res);
}
}
@Override
public void init(FilterConfig filterConfig) {}
@Override
public void destroy() {}
}
在application.properties
或application.yml
中添加过滤器配置:
spring.mvc.filter.cors.enabled=true
或者手动注册过滤器:
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean<CorsFilter> corsFilter() {
FilterRegistrationBean<CorsFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new CorsFilter());
registrationBean.addUrlPatterns("/*");
registrationBean.setName("corsFilter");
registrationBean.setOrder(1);
return registrationBean;
}
}
以下是一个典型的跨域请求处理流程图:
sequenceDiagram participant Browser as 浏览器 participant Server as 后端服务器 participant Nginx as Nginx代理 Note over Browser: 发起跨域请求 Browser->>Nginx: 请求 -> http://localhost/api/test Nginx->>Server: 转发请求 -> http://localhost:8081/test Server-->>Nginx: 返回响应数据 Nginx-->>Browser: 返回响应数据给浏览器
*
,特别是allowedOrigins
字段,应明确指定可信的域名。OPTIONS
请求,后端需正确响应。