使用Filter实现CORS跨域请求

在Java Web应用中,可以通过自定义Filter来处理跨域请求,主要涉及设置CORS(跨域资源共享)相关的HTTP响应头。以下是详细实现步骤:

实现跨域处理的Filter示例

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class CorsFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化操作(可选)
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
            throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        // 设置CORS响应头
        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, X-Requested-With");
        response.setHeader("Access-Control-Max-Age", "3600"); // 预检请求缓存时间(秒)
        response.setHeader("Access-Control-Allow-Credentials", "true"); // 允许携带凭证(如Cookie)

        // 处理预检请求(OPTIONS方法)
        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
            return; // 直接返回,不继续执行过滤器链
        }

        // 继续执行后续过滤器或目标资源
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        // 清理操作(可选)
    }
}

关键配置说明

  1. Access-Control-Allow-Origin

    • * 允许所有域(开发环境常用)
    • 生产环境建议指定具体域名(如 https://yourdomain.com
  2. Access-Control-Allow-Methods
    定义允许的HTTP方法,如 GET, POST, PUT, DELETE

  3. Access-Control-Allow-Headers
    允许的请求头,如 Content-Type, Authorization

  4. Access-Control-Max-Age
    预检请求(OPTIONS)的结果缓存时间,减少重复预检请求

  5. Access-Control-Allow-Credentials
    当需要携带Cookie等凭证时设置为 true,此时 Allow-Origin 不能为 *

动态域名处理(可选)

如果需要根据请求动态设置允许的域名:

String origin = request.getHeader("Origin");
if (allowedOrigins.contains(origin)) { // 检查域名白名单
    response.setHeader("Access-Control-Allow-Origin", origin);
}

在web.xml中注册Filter

<filter>
    <filter-name>CorsFilterfilter-name>
    <filter-class>com.example.CorsFilterfilter-class>
filter>
<filter-mapping>
    <filter-name>CorsFilterfilter-name>
    <url-pattern>/*url-pattern>
filter-mapping>

注意事项

  1. 安全考虑

    • 生产环境避免使用 Access-Control-Allow-Origin: *
    • 建议维护域名白名单
  2. 携带凭证
    当使用 Access-Control-Allow-Credentials: true 时:

    • 前端需要设置 withCredentials: true(如axios)
    • Allow-Origin 必须明确指定域名(不能为*
  3. 复杂请求处理
    PUT/DELETE等非简单请求会先发送OPTIONS预检请求,需正确处理

  4. Header顺序
    建议在chain.doFilter()之前设置响应头,确保头信息被正确添加

Spring Boot的替代方案

如果使用Spring Boot,可直接使用@CrossOrigin注解或全局配置:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("https://yourdomain.com")
                .allowedMethods("*")
                .allowedHeaders("*")
                .allowCredentials(true);
    }
}

通过Filter处理跨域的优势在于可以统一管理所有请求的CORS策略,特别是在需要与身份验证等其它过滤器配合使用时,能确保正确的执行顺序。

你可能感兴趣的:(spring)