最近实践了一把SpringCloud集成注册中心、网关、配置中心、微服务,恰好电脑上的redis出现了各种问题,索性不用redis,自己写了个中间件,将存储到了MySQL中。下面是期间遇到的各种问题总结。
手先介绍基实现的本原理。我请教了下师傅,总结出了将Session持久化的几条要点。
- Http是无状态的协议;
所谓http是无状态协议,言外之意是说http协议没法保存客户机信息,也就没法区分每次请求的不同之处,服务器无法区分通过http发送的请求是来源于甲用户还是来源于乙用户的。关于http无状态阻碍了交互式应用程序的实现。比如记录用户浏览哪些网页、判断用户是否拥有权限访问等。于是,两种用于保持HTTP状态的技术就应运而生了,一个是Cookie,而另一个则是Session。
2.Fetch是默认不携带cookies的;
|
|
response.setHeader(“Access-Control-Allow-Credentials”,”true”);
response.setHeader(“Access-Control-Allow-Origin”, “http://192.168.0.1“);
3.Cookis是不允许跨域的;
Cookie一班是不允许跨域传递的,解决方案除了上面那种,还可以通过Nginx;
解决cookie跨域问题之nginx反向代理
4.浏览器是通过OPTION请求获取服务器对请求的支持信息;
OPTIONS 方法比较少见,该方法用于请求服务器告知其支持哪些其他的功能和方法。通过 OPTIONS 方法,可以询问服务器具体支持哪些方法,或者服务器会使用什么样的方法来处理一些特殊资源。可以说这是一个探测性的方法,客户端通过该方法可以在不访问服务器上实际资源的情况下就知道处理该资源的最优方式。
5.既然比较少见,什么情况下会使用OPTION这个方法呢?
当发送的请求为简单请求的时候,服务器会自动在响应的头部添加添加一个Origin字段,其值将被自动设置为对应的请求域,
Origin: http://api.bob.com
因此可以说,对与简单请求是不存在跨域问题的。A)、什么是简单请求呢?
浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。
只要同时满足以下两大条件,就属于简单请求。
(1) 请求方法是以下三种方法之一:
HEAD
GET
POST
(2)HTTP的头信息不超出以下几种字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
凡是不同时满足上面两个条件,就属于非简单请求。
浏览器对这两种请求的处理,是不一样的。
凡是不同时满足上面两个条件,就属于非简单请求。 浏览器对这两种请求的处理,是不一样的。
非简单请求是那种对服务器有特殊要求的请求,比如请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json。
非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为”预检”请求(preflight)。
浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。
6.Session是通过Cookies中的信息来识别的;
当解决了跨域和cookie携带的问题,以后每次浏览器发送请求就会携带一个cookie的信息,那么Session和JSESessionId是如何产生联系的?
首先我们需要知道Session在何时创建呢?
sessionid如何产生?由谁产生?保存在哪里?
当然还是在服务器端程序运行的过程中创建的,不同语言实现的应用程序有不同创建Session的方法,而在Java中是通过调用HttpServletRequest的getSession方法(使用true作为参数)创建的。在创建了Session的同时,服务器会为该Session生成唯一的Session id,而这个Session id在随后的请求中会被用来重新获得已经创建的Session;在Session被创建之后,就可以调用Session相关的方法往Session中增加内容了,而这些内容只会保存在服务器中,发到客户端的只有Session id;当客户端再次发送请求的时候,会将这个Session id带上。
服务器上为每个用户都保存了一个session,那当用户请求过来的时候是怎么知道某一个用户应该对应哪个session呢?
这时jsessionid就派上用场了。每一个session都有一个id来作为标识,这个id会传到客户端,每次客户端请求都会把这个id传到服务器,服务器根据id来匹配这次请求应该使用哪个session。jsessionid就是客户端用来保存sessionid的变量,主要是针对j2ee实现的web容器,没有研究过其他语言是用什么变量来保存的。一般对于web应用来说,客户端变量都会保存在cookie中,jsessionid也不例外。不过与一般的cookie变量不同,jsessionid是保存在内存cookie中的,在一般的cookie文件中是看不到它的影子的。内存cookie在打开一个浏览器窗口的时候会创建,在关闭这个浏览器窗口的时候也同时销毁。这也就解释了为什么session变量不能跨窗口使用,要跨窗口使用就需要手动把jsessionid保存到cookie里面。
下面看代码:
|
|
|
|
其实所有的根本就是获取有效的SessionId就可以了。参考文章都在上面了,里面结合了我的理解和参考的内容,希望可以帮助到大家。
夏天了,又到了长肉的季节了。。。。。。