一般你可以自己实现Filter

@Component
public class CrossFilter implements Filter {
    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        // TODO 这里添加你要设置的响应头。        
    }

}

你需要记住的是:跨域保护,目的是保护用户在该服务端的权益,保护的是服务端。所以,跨域问题的解决绝大多数都是解决服务端设置的问题。
springboot自带的Filter,如下:

import java.util.Arrays;
import java.util.List;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;


@Configuration
public class WebConfig {
    private List<String> allowDomains =Arrays.asList("http://tools.bigbrotherlee.com","http://localhost:8080");
    private List<String> allowHeaders =Arrays.asList("Authorization","Cookie","Token","content-type");
    private List<String> exposedHeaders=Arrays.asList("Content-Disposition");
    
    @Bean
    public CorsFilter corsFilter() {
        // 1.添加CORS配置信息
        CorsConfiguration config = new CorsConfiguration();
        // 1) 允许通过的域,不要写*,否则cookie就无法使用了
        allowDomains.forEach(config::addAllowedOrigin);
        // 2) 是否发送Cookie信息
        config.setAllowCredentials(true);
        // 3) 允许的请求方式
        config.addAllowedMethod("*");
        // 4)允许的头信息
        allowHeaders.forEach(config::addAllowedHeader);
        config.setExposedHeaders(exposedHeaders);
        // 2.添加映射路径,我们拦截一切请求
        UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
        configSource.registerCorsConfiguration("/**", config);
        // 3.返回新的CorsFilter.
        return new CorsFilter(configSource);
    }
}
  1. 参数
    只有五个参数,他们是向关联的
    // setAllowedOrigins 设置允许跨域的域名,可以使用表示所有域名 可以使用.xxx.com表示所有子域名,在设置为AllowCredentials为true的时候不允许使用*
    configuration.setAllowedOrigins(List.of("http://localhost:5173"));
    // setAllowedMethods设置允许跨域的method,可以使用*表示全部
    configuration.setAllowedMethods(List.of("*"));
    // setAllowedHeaders设置允许携带的header,这里需要包含所有你需要的非正常允许的header,包括你自己自定义的
    configuration.setAllowedHeaders(List.of("*"));
    // 允许的自定义header
    configuration.setExposedHeaders(List.of("*"));
    // 是否允许携带认证信息(敏感信息),比如Cookie,在设置为true的时候不允许AllowedOrigins通配符,
    // 同时前端需要配合设置withCredentials才会携带Cookie
    configuration.setAllowCredentials(true);

// 携带Cookie
在跨域的服务端给前端设置Cookie时需要同时设置

  1. cookie.setAttribute("SameSite", "None"); // 表示不是同源Cookie
  2. cookie.setSecure(true); // 表示只在https环境下

此时在https环境下设置Cookie就会浏览器保存了,否则都不会保存。

可以看到,为了保护浏览器自带行为的Cookie,做了很多限制,所以在通常情况下我们不使用Cookie,而是自定义header比如token来做跨域

另外:
一些请求:比如有自定义头,非get,post,head请求或者带有Cookie这样的有用户隐私的头;需要在浏览器做正式请求服务器动作之前会先做一个options请求以确定服务端允不允许。总之,跨域是为了保护服务端和保护用户在服务端的数据(包括服务端存在本地与服务端存在远端的数据)。

标签: springboot, spring

添加新评论