工作一段时间后发现,纠缠最多的,摔的最狠的,还是这些基础性的东西。
1、Cookie与Session的用法
Cookie只能存储简单的数据,如字符串、数字、布尔值(C#中对Cookie赋值只能是字符串),Session可以存储复杂的数据结构。
js读写Cookie:
//写cookies
function setCookie(name, value, second) {
if (!second) {
second = 7 * 24 * 60 * 60;//默认7天
}
var exp = new Date();
exp.setTime(exp.getTime() + second * 1000);
document.cookie = name + "=" + escape(value) + ";expires=" + exp.toGMTString() + ";path=/";
}
//读取cookies
function getCookie(name) {
if (document.cookie.length > 0) {
c_start = document.cookie.indexOf(name + "=");//获取字符串的起点
if (c_start != -1) {
c_start = c_start + name.length + 1;//获取值的起点
c_end = document.cookie.indexOf(";", c_start);//获取结尾处
if (c_end == -1) c_end = document.cookie.length;//如果是最后一个,结尾就是cookie字符串的结尾
return decodeURI(document.cookie.substring(c_start, c_end));//截取字符串返回
}
}
return "";
}
C#读写Cookie:
//添加Cookie方法一:
Response.Cookies[key].Value = "1";
Response.Cookies[key].Domain = ".abc.com";
Response.Cookies[key].Expires = DateTime.Now.AddMinutes(20);
//添加Cookie方法二:
HttpCookie cookie = new HttpCookie(key);
cookie.Value = "1";
cookie.Expires = DateTime.Now.AddMinutes(20);
cookie.Domain = ".abc.com";
Response.Cookies.Add(cookie);
//获取Cookie方法
HttpCookie cookie = Request.Cookies[key];
if (cookie!=null)
{
string cValue = cookie.Value.ToString();
}
C#读写Session
//添加session
Session["name"] = "张三";
//获取session
if (Session["name"]!=null)
{
string name = Session["name"].ToString();
}
2、Cookie、Session存储的位置
Cookie存储在客户端,在客户端PC上以文件形式存在,如谷歌浏览器的Cookie存储在个人电脑的这个位置:C:\Users\Administrator\AppData\Local\Google\Chrome\User Data\Default\Cache
浏览器对存储的Cookie有校验、如果Cookie被修改,浏览器会检测到并删除。
Session存储在服务端,通常是存储在内存中,通过存储在Cookie中的sessionid建立起客户端与服务端的联系。
3、Cookie相对Session的优点,Session相对Cookie的优点
Cookie前后端都能进行读写操作,Session只能在服务端进行读写操作;
Session存储复杂的数据结构比较方便,Cookie需要把数据结构转换为字符串;
Cookie对用户可见,Session对用户不可见;
如使用前端页面缓存策略,如:Squid,不进行例外处理,服务端的Session操作不会执行;
4、Session的存储方式
进程、状态服务、关系数据库、非关系数据库redis
5、session与cookie的关系
一般情况下session的主要数据都存储在服务端,但session有个key(也可以理解成id),这个key是存储在cookie中的,而服务端就是根据这个key来判断是不是同一个会话,所以session是依赖于cookie的,浏览器禁用cookie后session也会失效,同时如果你打开两个浏览器,服务端不会判断为同一个会话的,因为这两个session的key值不一样。在asp.net中,它的名字是ASP.NET_SessionId,在java中,它的名字是JSESSIONID。
6、服务端是如何操作客户端浏览器中cookie的
服务端的cookie操作会添加在Http请求的Header中,Response Headers中的set-cookie,包括cookie的名称、内容、作用域、过期时间,然后浏览器会执行相应的Cookie添加、更新操作,如下图:
7、负载均衡中Session的使用,Session的统一管理
负载均衡涉及到多台服务器,需要明确的一点是,session服务和IIS是相互独立的,多台服务器共享session就需要对session进行统一管理,最简单的办法是所有负载服务器的session都采用状态服务,同时指向同一个地址,该状态服务器可以是负载服务器中的一台,也可以是单独的一台,只负责session的状态服务,配置如下:
在web.config的system.web节点中添加(需要确保的是该服务器的状态服务允许远程连接)
<sessionState mode="StateServer" stateConnectionString="tcpip=192.168.0.188:42424" useHostingIdentity="true"/>
8、前后端分离中再造一个Session
理解了session的本质,然后结合cookie实现一个类似session的功能也就比较简单了,这通常在前后端分离中比较实用,大概思路如下:
(1)用户第一次请求时生成一个随机数来作为用户的身份标识sessionkey,可以借助guid来生成,简单而且不会冲突(担心guid长度过长也可以使用时间戳+随机数)。
(2)客户端在接收到生成的sessionkey后,把session存储在cookie中或添加在后续的http请求头中,供服务端使用,验证用户身份。
(3)服务端将sessionkey作为键值或键值的一部分,将所需的数据存储在内存或redis中
//模拟session设置
public void SetSession(string sessionKey, string key, string value, int second)
{
RedisHelper.String_set(sessionKey + key, value, second);
}
//模拟session获取
public string GetSession(string sessionKey, string key)
{
if (RedisHelper.KeyExists(sessionKey + key))
{
return RedisHelper.String_get(sessionKey + key);
}
else
{
return null;
}
}
上面代码中存储的是字符串,复杂的数据结构可以使用万能的json格式来实现