【跨域解决】

跨域

跨域(Cross-Origin)

是指在Web开发中,当一个网页的脚本试图访问来自不同源(即协议、域名或端口号任意一个不同)的资源时,就会发生跨域问题。这是出于安全考虑,浏览器限制了跨域访问,防止恶意脚本窃取用户信息或对其他网站造成攻击。

常见的跨域

  1. AJAX请求跨域:当一个网页通过AJAX请求访问另一个域名下的资源时,由于浏览器的同源策略,会产生跨域问题。
  2. 嵌入第三方资源:当一个网页嵌入来自其他域名的图片、视频、广告等资源时,如果该资源所在的域名与当前页面的域名不同,也会发生跨域问题。
  3. 跨窗口通信:当网页中的两个窗口(如iframe)分别来自不同的域名,且它们需要进行数据交互时,也会遇到跨域问题。
  4. 域名跳转:当一个网站将用户从一个域名重定向到另一个域名时,也会涉及跨域问题。
  5. CDN加速:当网站使用CDN服务加速静态资源时,由于CDN服务器可能位于不同的域名下,访问静态资源也可能出现跨域问题。

springboot中常见的跨域解决方案

1.使用 @CrossOrigin 注解:可以在Controller层方法上使用该注解,允许特定来源的请求跨域访问。

// 允许所有来源的GET和POST请求访问该Controller:
@RestController
@CrossOrigin
public class MyController {

    @GetMapping("/hello")
    public String hello() {
        return "Hello World!";
    }

    @PostMapping("/save")
    public void save(@RequestBody User user) {
        // 保存用户信息
    }
}

// 允许特定来源的所有请求访问该Controller,并允许携带凭证信息:
@RestController
@CrossOrigin
public class MyController {

    @GetMapping("/hello")
    public String hello() {
        return "Hello World!";
    }

    @PostMapping("/save")
    public void save(@RequestBody User user) {
        // 保存用户信息
    }
}


2.配置WebMvcConfigurer:通过实现WebMvcConfigurer接口,在其addCorsMappings方法中配置跨域规则。

/**
*	方法一:
		allowCredentials(true) 时,allowedOrigins("*") 是互相矛盾的此时只能具体到对应域名
*/
@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("*")
                .allowedHeaders("*")
                .allowCredentials(true)
                .maxAge(3600);
    }
}

 @Bean
 public CorsFilter corsFilter() {
     return new CorsFilter(httpServletRequest -> {
         CorsConfiguration config = new CorsConfiguration();
         config.setAllowCredentials(false);
         config.addAllowedOrigin("*");
         config.addAllowedHeader("*");
         config.addAllowedMethod("*");
         config.setMaxAge(3600L);
         return config;
     });
 }

3.使用Filter过滤器:创建一个Filter来拦截请求,在响应头中添加Access-Control-Allow-Origin等相关的响应头信息。


/**
 * Access-Control-Allow-Origin 设置为 * 表示允许所有来源进行跨域请求。
 * Access-Control-Allow-Credentials 设置为 true 表示允许携带凭证信息进行跨域请求。
 * Access-Control-Allow-Methods 设置为 GET, POST, PUT, DELETE, OPTIONS 表示允许的HTTP方法。
 * Access-Control-Max-Age 设置为 3600 表示预检请求(OPTIONS请求)的缓存时间。
 * Access-Control-Allow-Headers 设置为一组允许的请求头字段。
 */
@Component
public class MyCorsFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest request = (HttpServletRequest) req;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, Accept, X-Requested-With, remember-me,token");
        if (request.getMethod().equals("OPTIONS")) {
            response.setStatus(HttpServletResponse.SC_OK);
        } else {
            chain.doFilter(req, res);
        }
    }
}

// 配置完过滤器后,需要将过滤器注册到 springboot 当中
@Bean
public FilterRegistrationBean<MyCorsFilter> corsFilterRegistry() {
    FilterRegistrationBean<MyCorsFilter> bean = new FilterRegistrationBean<>(new MyCorsFilter());
    bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
    return bean;
}

4.使用Spring Security:如果项目中使用了Spring Security,可以通过配置HttpSecurity来实现跨域访问控制。

@Configuration
@EnableWebSecurity
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().and()
            // 其他HttpSecurity配置
            .authorizeRequests()
            .antMatchers("/public/**").permitAll()
            .anyRequest().authenticated()
            .and().formLogin();
    }

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("*"));
        configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE"));
        configuration.setAllowedHeaders(Arrays.asList("Content-Type", "Authorization"));
        configuration.setExposedHeaders(Arrays.asList("Authorization", "X-Total-Count"));
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
}

VUE调试阶段

const instance = axios.create({
    baseURL: process.env.VUE_APP_BASEURL,
    withCredentials: false
})

Nginx 跨域解决

可以在Nginx的配置文件中添加以下代码来设置响应头信息:

location /api {
    add_header 'Access-Control-Allow-Origin' '*';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
    add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
    if ($request_method = 'OPTIONS') {
        return 204;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值