文章目录
什么是跨域问题?
当域名,端口,协议三者存在任意一项不同时就需要解决跨域问题
实现方式
实现 HandlerInterceptor
创建一个类实现 HandlerInterceptor 接口,并在 preHandle 方法中设置响应头以实现跨域。
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")// 拦截所有的请求
.allowedOrigins("*")// 可跨域的域名,*为所有
.allowCredentials(true)
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")// 允许跨域的方法,可以单独配置
.maxAge(3600);
}
}
重写 WebMvcConfigurer(全局跨域)
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")// 拦截所有的请求
.allowedOrigins("*")// 可跨域的域名,*为所有
.allowCredentials(true)
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")// 允许跨域的方法,可以单独配置
.maxAge(3600);
}
}
使用@CrossOrigin注解 (局部跨域)
使用自定义filter实现跨域
创建一个类实现 javax.servlet.Filter 接口,并在 doFilter 方法中设置响应头以实现跨域。
@WebFilter
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", "http://example.com");
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
response.setHeader("Access-Control-Allow-Credentials", "true");
chain.doFilter(req, res);
}
// ...
}
注意:使用 Filter 实现跨域时,Filter 会拦截所有请求,而不仅仅是跨域请求。因此,在设置响应头时需要谨慎,避免影响其他请求的正常处理。如果需要更细粒度的控制,可以考虑使用 @CrossOrigin 注解或拦截器来实现。
在响应头中添加 Access-Control-Allow-Origin 等字段,如果希望允许所有域名访问 API,可以将值设置为 *:
response.setHeader("Access-Control-Allow-Origin", "http://example.com")
使用 Nginx 配置
location / {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
if ($request_method = 'OPTIONS') {
return 204;
}
}
配置 Gateway 的路由
- id: my_route
uri: http://localhost:8080
predicates:
- Path=/api/**
filters:
- RewritePath=/api/(?<segment>.*), /$\{segment}
- AddResponseHeader=Access-Control-Allow-Origin:http://example.com
- AddResponseHeader=Access-Control-Allow-Methods:GET, POST, PUT, DELETE
- AddResponseHeader=Access-Control-Allow-Headers:Content-Type, Authorization
- AddResponseHeader=Access-Control-Allow-Credentials:true
这将允许来自 http://example.com 的跨域请求访问 Gateway 中的 API。