SpringBoot 前后端分离跨域问题解决

Posted Lam

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringBoot 前后端分离跨域问题解决相关的知识,希望对你有一定的参考价值。

一、关于跨域介绍

1)什么是跨域?

跨域是指不同的域名之间的相互访问。跨域,指的是浏览器不能执行其它网站的脚本。它是由浏览器的同源策略造成的,是浏览器对 JavaScript 施加的安全限制。

也就是说,网站A 获取 网站B 的数据,如果 网站A 和 网站B 不在同一个域中就出现了跨域的问题。

2)什么是同一个域?

同一协议,同一IP,同一端口,只要其中一种不同就产生了跨域。 

二、SpringBoot 跨域(@CrossOrigin)

1)@CrossOrigin 使用场景要求

JDK 1.8+

SpringBoot 4.2+

2)@CrossOrigin 源码解析

@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;

3)@CrossOrigin 使用

后端:localhost:9999

采用 SpringBoot 注解 @CrossOrigin ,在 Controller 层需要跨域的类或方法上添加该注解。

@RestController
public class JsonController 

    @RequestMapping("/test")
    @ResponseBody
    public String test() 
        return "测试!";
    

    /**
     * CrossOrigin: 实现跨源资源共享(CORS)
     * origin="*",代表所有域名都可访问
     * maxAge 飞行前响应的缓存持续时间的最大年龄,简单来说就是Cookie的有效期 单位为秒;若maxAge是负数,则代表为临时Cookie,不会被持久化,Cookie信息保存在浏览器内存中,浏览器关闭Cookie就消失。
     */
    @CrossOrigin(origins = "*", maxAge = 3600)
    @RequestMapping(value = "/hello")
    @ResponseBody
    public Map hello() 
        HashMap<String, String> map = new HashMap<>();
        map.put("username", "林北");
        map.put("age", "46");
        map.put("city", "台");
        map.put("worker", "卖鱼");
        return map;
    

前端:localhost:63342 跨域请求 localhost:9999

<input type="button" value="Test" onclick="test()"/>
<input type="button" value="Hello" onclick="hello()"/>

<!-- axios -->
<script src="https://unpkg.com/axios@0.21.0/dist/axios.min.js"></script>
<script>
    function test() 
        this.axios.get("http://localhost:9999/test")
            .then(function (response) 
                console.log(response);
            )
            .catch(function (error) 
                console.log(error)
            )
    

    function hello() 
        this.axios.get("http://localhost:9999/hello")
            .then(function (response) 
                console.log(response);
            )
            .catch(function (error) 
                console.log(error)
            )
    
</script>

访问后端未解决跨域方法 test,出现跨域问题

访问后端跨源资源共享方法 hello,成功获取数据

 

以上是关于SpringBoot 前后端分离跨域问题解决的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot前后端分离跨域解决方案

Nginx 前后端分离及跨域问题

前后端分离跨域问题解决方案

SpringBoot2.5解决跨域问题2021年秋季新方法 SpringBoot+Vue前后端分离解决session不一致的问题

springboot shiro 前后端分离,解决跨域过虑options请求shiro管理session问题模拟跨域请求

前后端分离项目,如何解决跨域问题