Web项目前后端分离导致跨域问题的解决

在编写 SpringBoot 前后端分离项目时, 出现了一个问题: 前端无法得到后端响应的数据, 浏览器对请求进行了拦截

原因: 前端调用的后端接口和前端不属于同一个域, 就会产生跨域问题, 也就是说你的应用访问了该应用域名或端口之外的域名或端口

要同时满足三个条件才会产生跨域问题,这也就是为什么会产生跨域的原因。

  1. 浏览器限制,而不是服务端限制
  2. 请求地址的域名或端口和当前访问的域名或端口不一样
  3. 发送的是 XHR(XMLHttpRequest)请求,可以使用 a 标签(模拟xhr请求)和 img 标签(模拟json请求)做对比(控制台只报了一个跨域异常)

解决思路:

  • 浏览器解除跨域问题 (可以但不合理)
  • 用 JSONP 代替 XHR 请求 (不好用)
  • CORS 方案 (好用)

CORS 跨域共享

跨源资源共享(Cross-origin resource sharing, CORS)是由大多数浏览器实现的 W3C 规范,它允许您以灵活的方式指定哪种跨域请求被授权,而不是使用一些不太安全、功能不太强大的方法,比如 IFRAME 或 JSONP

方案具体原理这里不赘述

在 Spring Boot 中使用带有 @CrossOrigin 注释的 Controller 方法 CORS 配置,不需要任何特定的配置 (如果仍然有跨域问题, 1. 请检查访问地址是否出现错误 2. 请求方法(一级映射和二级均需要 如/user/login 中的 user 和 login)需要指定请求方式 Post / Get)

//实现跨域注解
//origin="*" 代表所有域名都可访问, 可以省略
//maxAge 响应的缓存持续时间的最大年龄,简单来说就是 Cookie 的有效期 单位为秒
//若 maxAge 是负数,则代表为临时 Cookie,不会被持久化, Cookie 信息保存在浏览器内存中,浏览器关闭 Cookie 就消失

源码:

@Target({
    
     ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CrossOrigin {
    
    

    String[] DEFAULT_ORIGINS = {
    
     "*" };

    String[] DEFAULT_ALLOWED_HEADERS = {
    
     "*" };

    boolean DEFAULT_ALLOW_CREDENTIALS = true;

    long DEFAULT_MAX_AGE = 1800;


    /**
     * 同origins属性一样
     */
    @AliasFor("origins")
    String[] value() default {
    
    };

    /**
     * 所有支持域的集合,例如"http://domain1.com"。
     * <p>这些值都显示在请求头中的Access-Control-Allow-Origin
     * "*"代表所有域的请求都支持
     * <p>如果没有定义,所有请求的域都支持
     * @see #value
     */
    @AliasFor("value")
    String[] origins() default {
    
    };

    /**
     * 允许请求头重的header,默认都支持
     */
    String[] allowedHeaders() default {
    
    };

    /**
     * 响应头中允许访问的header,默认为空
     */
    String[] exposedHeaders() default {
    
    };

    /**
     * 请求支持的方法,例如"{RequestMethod.GET, RequestMethod.POST}"}。
     * 默认支持RequestMapping中设置的方法
     */
    RequestMethod[] methods() default {
    
    };

    /**
     * 是否允许cookie随请求发送,使用时必须指定具体的域
     */
    String allowCredentials() default "";

    /**
     * 预请求的结果的有效期,默认30分钟
     */
    long maxAge() default -1;

}

猜你喜欢

转载自blog.csdn.net/qq_45560445/article/details/121346061
今日推荐