欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring Boot 2.X 如何优雅的解决跨域问题?

程序员文章站 2022-03-30 11:31:40
一、什么是源和跨域 源(origin)就是协议、域名和端口号。URL由协议、域名、端口和路径组成,如果两个URL的协议、域名和端口全部相同,则表示他们同源。否则,只要协议、域名、端口有任何一个不同,就是跨域。 二、什么是同源策略? 同源策略(Same origin policy)是一种约定,它是浏览 ......

一、什么是源和跨域

源(origin)就是协议、域名和端口号。
url由协议、域名、端口和路径组成,如果两个url的协议、域名和端口全部相同,则表示他们同源。否则,只要协议、域名、端口有任何一个不同,就是跨域。

对https://www.baidu.com/index.html进行跨域比较:
url 是否跨域 原因
https://www.baidu.com/more/index.html 不跨域 三要素相同
https://map.baidu.com/ 跨域 域名不同
http://www.baidu.com/index.html 跨域 协议不同
https://www.baidu.com:81/index.html 跨域 端口号不同

二、什么是同源策略?

同源策略(same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。

同源策略又分为以下两种:

  1. dom同源策略:禁止对不同源页面dom 进行操作。这里主要场景是iframe跨域的情况,不同域名的iframe是限制互相访问的。
  2. xmlhttprequest同源策略:禁止使用xhr对象向不同源的服务器地址发起http请求。

三、spring boot跨域解决方案

本例使用spring boot 2.1.2.release演示,分别用8080和8081端口启动,部分代码如下:

跨域页面:testotherdomain.html

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>不同域名-java碎碎念</title>
</head>
<body>
<button id="b1">点我测试</button>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
<script>
    $("#b1").click(function () {
        $.ajax({
            url: "http://localhost:8081/hello",
            type: "post",
            success:function (res) {
                console.log(res);
            }
        })
    });
</script>
</body>
</html>

接口类:hellocontroller

package com.example.hellospringboot.controller;

import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.restcontroller;

@restcontroller
public class hellocontroller {
    @requestmapping("/hello")
    public string hellospring (){
        return "hello java碎碎念!";
    }
}

 未解决跨域前运行截图:

Spring Boot 2.X 如何优雅的解决跨域问题?

 

在spring boot 2.x应用程序中可以使用注解@crossorigin,也可以通过使用webmvcconfigurer对象来定义全局cors配置。

  1. @crossorigin注解示例代码
package com.example.hellospringboot.controller;

import org.springframework.web.bind.annotation.crossorigin;
import org.springframework.web.bind.annotation.requestmapping;
import org.springframework.web.bind.annotation.restcontroller;

@restcontroller
public class hellocontroller {

    @crossorigin
    @requestmapping("/hello")
    public string hellospring (){
        return "hello java碎碎念!";
    }
}

  2. webmvcconfigurer对象示例代码

package com.example.hellospringboot.config;

import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.configuration;
import org.springframework.web.servlet.config.annotation.corsregistry;
import org.springframework.web.servlet.config.annotation.webmvcconfigurer;

@configuration
public class myconfiguration {
    @bean
    public webmvcconfigurer corsconfigurer() {
        return new webmvcconfigurer() {
            @override
            public void addcorsmappings(corsregistry registry) {
                registry.addmapping("/*")
                          .allowedorigins("*")
                          .allowcredentials(true)
                          .allowedmethods("get", "post", "delete", "put","patch")
                          .maxage(3600);
            }
        };
    }
}

 

按照上面两种方式的一种配置完成后,即可实现对跨域的支持,运行成功截图如下:

Spring Boot 2.X 如何优雅的解决跨域问题?

 

完整源码地址:https://github.com/suisui2019/hellospringboot

推荐阅读

1.redis cluster搭建高可用redis服务器集群
2.为什么单线程的redis这么快?
3.spring boot集成spring session实现session共享
4.spring boot入门-快速搭建web项目
5.spring boot2.0整合redis
6.一篇文章搞定springmvc参数绑定


限时领取免费java相关资料,涵盖了java、redis、mongodb、mysql、zookeeper、spring cloud、dubbo/kafka、hadoop、hbase、flink等高并发分布式、大数据、机器学习等技术。
关注下方公众号即可免费领取:

Spring Boot 2.X 如何优雅的解决跨域问题?