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

SpringBoot系列(八)分分钟学会Springboot多种解决跨域方式

程序员文章站 2022-03-25 17:02:08
本文讲述了跨域的产生原因,原理,以及同源策略的概念,然后介绍了在SpringBoot解决跨域的三种方式,分别是利用CrossOrgin注解,全局配置Mvc,然后就是利用过滤器配置,过滤器有两种方式,有一种是利用servlet的过滤器实现。 ......

springboot系列(八) 分分钟学会springboot多种跨域解决方式

往期推荐
springboot系列(一)idea新建springboot项目

springboot系列(二)入门知识

springboot系列(三)配置文件详解

springboot系列(四)web静态资源配置详解

springboot系列(五)mybatis整合完整详细版

springboot系列(六)集成thymeleaf详解版

springboot系列(七) 集成接口文档swagger,使用,测试

** 目录 **

1. 跨域怎么理解

跨域是什么?

 跨域是指不同域名之间的相互访问,这是由浏览器的同源策略决定的,是浏览器对javascript施加的安全措施,防止恶意文件破坏。

同源策略:同源策略是一种约定,它是浏览器最核心的也是最基本的安全策略,如果缺少了同源策略,则浏览器的正常功能可能会受到影响。
所谓同源就是说协议域名端口号完全一致,有一个不一致就会造成跨域问题。

跨域原理:

  • 跨域请求能正常发出去,服务端能接受到请求并正常返回结果,只是结果被拦截了。
  • 跨域只存在于浏览器,不存在于其他平台,比如安卓/java/ios等平台。
  • 之所以会发生跨域是因为受到了同源策略的限制,同源策略要求源相同才能进行正常通信,即协议,域名,端口号都完全一致。

url :统一资源定位符,它是www的统一资源定位标志,也就是我们说的网络地址。它的一般格式为:协议类型://服务器地址:端口号/路径。
这也就是我们说的跨域中的域。

2. sprinboot中跨域的三种解决方法

跨域技术cors

 cors是一个w3c标准,全称是"跨域资源共享"(cross-origin resource sharing)。它允许浏览器向跨源服务器,发出xmlhttprequest请求,从而克服了ajax只能同源使用的限制。

 springboot 就对cross 做了很好的支持。目前有三种跨域方式。

1. crossorigin注解

//@crossorigin  表示所有的url均可访问此资源
@crossorigin(origins = "http://127.0.0.1:8093")//表示只允许这一个url可以跨域访问这个controller
@restcontroller
@requestmapping("/testcorss")
public class corssorigincontroller {

    //可以对方法运用该注解
    //@crossorigin(origins = "http://127.0.0.1:8093")
    @getmapping("/getstring")
    public string getstring(){
        return "跨域成功!";
    }

}

 代码说明:@crossorigin这个注解用起来很方便,这个可以用在方法上,也可以用在类上。如果你不设置他的value属性,或者是origins属性,就默认是可以允许所有的url/域访问。

  • value属性可以设置多个url。
  • origins属性也可以设置多个url。
  • maxage属性指定了准备响应前的缓存持续的最大时间。就是探测请求的有效期。
  • allowcredentials属性表示用户是否可以发送、处理 cookie。默认为false
  • allowedheaders 属性表示允许的请求头部有哪些。
  • methods 属性表示允许请求的方法,默认get,post,head。

2. 实现webmvcconfigurer

/**
 * @author 全栈学习笔记
 * @date 2020/4/21 12:04
 * @description
 */
public class mywebmvcconfig implements webmvcconfigurer {
    @override
    public void addcorsmappings(corsregistry registry) {
        registry.addmapping("/testcross/**")
                .allowedheaders("*")
                .allowedmethods("*")
                .allowcredentials(true)
                .allowedorigins("http://localhost:8093")
                .maxage(2000);
    }
}

 这个没什么好说的,就重写addcorsmappings方法就行,配置好参数,参数和上面的注解的参数类似。这个配置属于全局配置,配置好了全部的接口都遵循此规则。上面的注解方式只对类或者方法生效。addmaping是设置对那种格式的url生效,也就是跟在url后面的路径。

3. 过滤器配置

import org.springframework.boot.web.servlet.filterregistrationbean;
import org.springframework.context.annotation.bean;
import org.springframework.context.annotation.configuration;
import org.springframework.web.cors.corsconfiguration;
import org.springframework.web.cors.urlbasedcorsconfigurationsource;
import org.springframework.web.filter.corsfilter;

/**
 * @author 全栈学习笔记
 * @date 2020/4/21 12:49
 * @description
 */
@configuration
public class filter {
    @bean
    public filterregistrationbean corsfilter() {
        urlbasedcorsconfigurationsource source = new urlbasedcorsconfigurationsource();
        corsconfiguration config = new corsconfiguration();
        config.setallowcredentials(true);
        config.addallowedorigin("http://localhost:8093");//*表示允许所有
        config.addallowedheader("*");
        config.addallowedmethod("*");
        source.registercorsconfiguration("/**", config); // cors 配置对所有接口都有效
        filterregistrationbean bean = new filterregistrationbean(new corsfilter(source));
        bean.setorder(0);
        return bean;
    }

}

 利用过滤器配置实现跨域,还有另外一种方法

package com.example.democrossorigin.config;

import org.springframework.context.annotation.configuration;
import org.springframework.stereotype.component;

import javax.servlet.*;
import javax.servlet.filterconfig;
import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpservletresponse;
import java.io.ioexception;

@configuration
public class corssfilter implements filter {

    @override
    public void dofilter(servletrequest request, servletresponse response, filterchain chain)
            throws ioexception, servletexception {
        httpservletresponse res = (httpservletresponse) response;
        res.addheader("access-control-allow-credentials", "true");
        res.addheader("access-control-allow-origin", "http://localhost:8093");
        res.addheader("access-control-allow-methods", "get, post, delete, put");
        res.addheader("access-control-allow-headers", "content-type,x-caf-authorization-token,sessiontoken,x-token");
        chain.dofilter(request, response);
    }
    @override
    public void destroy() {
    }
    @override
    public void init(filterconfig filterconfig) throws servletexception {
    }
}

3. 跨域测试

 我们在新建一个springboot web项目,然后在resources 文件夹里面的static 新建一个index.html
代码如下

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>title</title>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
</head>
<body>
<div id="test"></div>
<input type="button" value="测试数据" onclick="getstring()"/>
</body>
<script>

    function getstring() {
        $.ajax({
            url:'http://localhost:8092/testcorss/getstring',
            type:'get',
            data:{},
            success:function (msg) {
                $("#test").html(msg);
            }
        })
    }
</script>
</html>

 我们模拟一个ajax请求,来请求我们的8092端口,运行新的项目结果
SpringBoot系列(八)分分钟学会Springboot多种解决跨域方式

 点击测试,发起请求

SpringBoot系列(八)分分钟学会Springboot多种解决跨域方式

 成功从一个项目里面拿到了另外一个项目的数据,就说明我们的跨域是成功了的。

4.总结:##

 本文讲述了跨域的产生原因,原理,以及同源策略的概念,然后介绍了在springboot解决跨域的三种方式,分别是利用crossorgin注解,全局配置mvc,然后就是利用过滤器配置,过滤器有两种方式,有一种是利用servlet的过滤器实现。如果你觉得本文有用的话!点个赞也不错哦!你的赞是对我最大的鼓励和支持。