首页 > 编程语言 > 详细

SpringBoot学会自己写配置类及跨域解析

时间:2020-03-04 09:01:26      阅读:103      评论:0      收藏:0      [点我收藏+]

?

前言

相信刚开始接触从xml配置文件转到java类实现配置功能的过程中,些许都会有些疑惑,配置文件到底该怎么写,我要实现多少接口,new多少对象,完全不知道怎么入手。

今天,在学习了跨域的相关配置后,学到了一点点自定义配置的思路。在此做下记录,也为学习讨论。本文主体分为两部分,第一部分介绍跨域问题,第二部分介绍如何编写配置类

?


?

聊聊跨域

跨域的本质是浏览器针对ajax请求,规定当前页面下发送的ajax请求的域名应该和当前页面的域名一致,达到阻止跨站攻击的目的。通常该跨域问题只针对ajax,而不会针对静态文件(图片等)

而以下四种情况会导致跨域问题:

条件 示例
域名不同 www.a.com与www.b.com
域名相同端口不同 www.a.com:80与www.a.com:81
二级域名不同 x.a.com与y.a.com
协议不同 http与https

?

解决跨域的方法

解决跨域的方法有以下三种

  • Jsonp

    • 实现方法:通过<script>标签的src发送请求路径获取伪装成js脚本的json数据

    • 缺点:只能发送GET请求,添加额外标签繁琐

  • nginx反向代理
    • 实现方法:修改nginx配置,添加二级域名到server的location路径下
    • 缺点:没解决本质问题,只是将跨域改为不跨越
  • CORS(推荐)
    • 实现方法:服务器端通知浏览器哪些域名可以跨域
    • 缺点:产生额外请求(预检请求)

?

什么是CORS?

CORS全称Cross-origin resource sharing(跨域资源共享)为W3C的一个标准,它允许浏览器向跨源服务器,发出XMLHttpRequest(ajax底层对象)请求,从而克服了AJAX只能同源使用的限制。

?

浏览器处理Ajax请求

浏览器处理ajax请求分为简单请求和特殊请求

简单请求

只要同时满足以下两大条件,就属于简单请求。:

(1) 请求方法是以下三种方法之一:

  • HEAD
  • GET
  • POST

(2)HTTP的头信息不超出以下几种字段:

  • Accept
  • Accept-Language
  • Content-Language
  • Last-Event-ID
  • Content-Type:只限于三个值application/x-www-form-urlencodedmultipart/form-datatext/plain

简单请求重点:

当浏览器发现发起的ajax请求是简单请求时,会在请求头中携带一个字段:Origin

简单请求过程解析:

浏览器会在请求头信息携带Origin字段(例:Origin:http://a.baidu.com{协议+域名+端口}),服务器根据该Origin值决定是否允许跨域

响应信息:

Access-Control-Allow-Origin: http://a.baidu.com 
Access-Control-Allow-Credentials: true
Content-Type: text/html; charset=utf-8
  • Access-Control-Allow-Origin:可接受的域,是一个具体域名或者*(代表任意域名)
  • Access-Control-Allow-Credentials:是否允许携带cookie,默认情况下,cors不会携带cookie,除非这个值是true

注意事项:

如果要使用cookie除了设置Access-Control-Allow-Credentials: true外,Access-Control-Allow-Origin: http://a.baidu.com必须为具体的域名!!!
?

特殊请求

除了简单请求之外,都为特殊请求

特殊请求重点:

特殊请求会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。该预检请求会在请求头携带一个OPTIONS字段

特殊请求过程解析(有关判断使用三元运算符?:)

发送预检请求==》服务器检查该域名是否在许可名单中?答复浏览,浏览器发送正式XMLHttpRequest请求:报错

预检请求模板:

OPTIONS /cors HTTP/1.1
Origin: http://a.baidu.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: X-Custom-Header
Host: api.leyou.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...

与简单请求相比,除了Origin以外,多了两个头:

  • Access-Control-Request-Method:接下来会用到的请求方式,比如PUT
  • Access-Control-Request-Headers:会额外用到的头信息

答复浏览器模板:

HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache/2.0.61 (Unix)
Access-Control-Allow-Origin: http://a.baidu.com
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: X-Custom-Header
Access-Control-Max-Age: 1728000
Content-Type: text/html; charset=utf-8
Content-Encoding: gzip
Content-Length: 0
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plain

除了Access-Control-Allow-OriginAccess-Control-Allow-Credentials以外,这里又额外多出3个头:

  • Access-Control-Allow-Methods:允许访问的方式
  • Access-Control-Allow-Headers:允许携带的头
  • Access-Control-Max-Age:本次许可的有效时长,单位是秒,过期之前的ajax请求就无需再次进行预检了

?

通过CorsFilter解决跨域

终于到了激动人心的撸码环节了,以下开始介绍如何编写配置类,以解决跨域问题

@Configuration注解

作用于类上,声明当前类为配置类,相当于xml文件

@Bean

作用于方法上,将当前方法的返回值对象注入spring容器上下文(contex)中

1. 明确需要返回的对象

因为本次为了解决跨域问题,所以需要使用CorsFilter对象。因此直接return new CorsFilter();

2. 查看该对象需要哪些参数

点进CorsFilter发现该构造方法需要一个CorsConfigurationSource对象作为参数

public CorsFilter(CorsConfigurationSource configSource) {
        Assert.notNull(configSource, "CorsConfigurationSource must not be null");
        this.configSource = configSource;
    }

所以需要new出一个CorsConfigurationSource的对象,但是点进CorsConfigurationSource发现该类为一个接口,因此应该找一个实现类进行实例化

3. 寻找接口实现类

点击该CorsConfigurationSource接口发现有一个实现类(UrlBasedCorsConfigurationSource)实现了该接口

public class UrlBasedCorsConfigurationSource implements CorsConfigurationSource

接着通过new该实现类(UrlBasedCorsConfigurationSource),通过阅读源码的注释了解到,该类下的registerCorsConfiguration可以注册CORS配置信息

     /**
     * Register a {@link CorsConfiguration} for the specified path pattern.
     */
    public void registerCorsConfiguration(String path, CorsConfiguration config) {
        this.corsConfigurations.put(path, config);
    }

根据该信息发现该方法需要两个参数,一个是需要拦截的路径,一个是配置类对象

4. 实例化配置类对象并注入相关信息

如法炮制,通过查看CorsConfiguration源码,发现该类可以直接new,并且有无参构造方法,所以,直接new对象,并对该对象属性赋初始值,完成该配置类的构造。

最后,将所有初始化后的对象赋值到方法的参数列表中

SpringBoot学会自己写配置类及跨域解析

原文:https://www.cnblogs.com/guaosky/p/12405755.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!