跨域问题的解决和跨域的原理(springboot)

跨域问题的解决和跨域的原理

什么情况下会发送跨域请求?

最常见场景:前后端分类项目会发送跨域

  • 前端将baseUrl写好并不能解决跨域问题
  1. 不同的协议:请求从 http 页面到 https 页面,或者从 https 页面到 http 页面。
  2. 不同的域名:例如从 example.com 请求 api.example.org
  3. 不同的端口:同一域名下的不同端口,例如从 example.com:80 请求 example.com:8080

浏览器的同源策略,限制了不同源之间的资源访问。

  • 不同源:
    • 不同协议
    • 不同域名
    • 不同端口
  • 原理
    • 预检请求 (Preflight Request): 对于某些跨域请求(尤其是复杂请求),浏览器会先发起一个 OPTIONS 请求来检查服务器是否允许实际请求。这称为预检请求。
      • Access-Control-Allow-Origin: 这是最核心的CORS头部,它告诉浏览器哪些来源的请求被允许。比如,Access-Control-Allow-Origin: https://example.com 允许 https://example.com 访问资源。
      • Access-Control-Allow-Methods: 指定允许的HTTP方法,比如 GET, POST, PUT
      • Access-Control-Allow-Headers: 指定允许的请求头部字段。
      • Access-Control-Allow-Credentials: 指定是否允许发送凭据(如Cookies或HTTP认证信息)。
  • 在不允许跨域时,进行跨域请求,会发生什么?是否报错?能否请求到资源
    • 浏览器阻止请求:当你尝试从一个源(例如 https://example.com)请求另一个源(例如 https://api.example.org)的资源时,如果目标服务器没有正确配置CORS头部,浏览器会阻止这次请求。
    • 控制台报错:浏览器的开发者工具控制台会显示错误信息,通常是关于CORS的错误。这些错误信息会指出请求被阻止的原因,例如:“CORS policy: No ‘Access-Control-Allow-Origin’ header” 或 “CORS policy: The ‘Access-Control-Allow-Origin’ header has a value ‘*’ that is not allowed” 等。

跨域请求

  • XMLHttpRequest(XHR): 用于通过JavaScript从客户端发起异步请求。
  • AJAX: 异步JavaScript和XML,用于动态加载数据。
  • restCilent: java中请求第三方接口

何如去解决跨域问题?

仅仅列举最常见解决方式

通过注解跨域

@RestController
@CrossOrigin(origins = "*")

配置类实现

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")//允许跨域的域名
                .allowedMethods("*")//允许任何方法
                .allowCredentials(false)//带上cookie信息
                .maxAge(3600) //maxAge(3600)表明在3600秒内,不需要再发送预检验请求,可以缓存该结果
                .allowedHeaders("*");
    }
}

通过crossFilter跨域

实现方式和上面基本一样

@Configuration // 一定不能忽略此注解
public class MyCorsFilter {
    @Bean
    public CorsFilter corsFilter() {
        // 1.创建 CORS 配置对象
        CorsConfiguration config = new CorsConfiguration();
        // 支持域
        config.addAllowedOriginPattern("*");
        // 是否发送 Cookie
        config.setAllowCredentials(true);
        // 支持请求方式
        config.addAllowedMethod("*");
        // 允许的原始请求头部信息
        config.addAllowedHeader("*");
        // 暴露的头部信息
        config.addExposedHeader("*");
        // 2.添加地址映射
        UrlBasedCorsConfigurationSource corsConfigurationSource = new UrlBasedCorsConfigurationSource();
        corsConfigurationSource.registerCorsConfiguration("/**", config);
        // 3.返回 CorsFilter 对象
        return new CorsFilter(corsConfigurationSource);
    }
}

通过Response跨域

@RestController
public class TestController {
    @RequestMapping("/test")
    public HashMap<String, Object> test(HttpServletResponse response) {
        // 设置跨域,上面原理中有解决
        response.setHeader("Access-Control-Allow-Origin", "*");
        return new HashMap<String, Object>() {{
            put("state", 200);
            put("data", "success");
            put("msg", "");
        }};
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值