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"。
     * 

这些值都显示在请求头中的Access-Control-Allow-Origin * "*"代表所有域的请求都支持 *

如果没有定义,所有请求的域都支持 * @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; }

你可能感兴趣的:(SpringBoot,前端,spring,boot,java)