前进中的蜗牛

番茄大叔

水滴穿石,非一日之功;没有量变,何来质变。

状态保持State

客户端与网站是通过Http协议传输数据的,Http是基于请求、响应的断开式网络协议。所以每次客户端的请求对服务端来说都是一个新的请求。那么怎样保持一些会话的,我将其分为两类:

  • 一类将需要保持的信息存入到浏览器端等下次请求时再发送给服务端
  • 二类将信息存到服务端,等请求再次请求时从服务端取出(这里其实有是再客户端存入一个key,服务端通过key取出保存的数据)

客户端保存

Url

一些简短的信息可写入到URL中,保存的形式一般再URL上添加{X{保存的信息}},在后台通过URL解析取出保存的信息,由于URL大小的限制一般保存的不会太大。token的身份认证应该通过这种方式

Cookie可以长期保存在客户端电脑文件中,当Cookie有效时每次请求都会自动附加Cookie信息。实现的原理是Http协议中Set-Cookie是设置Cookie指令。cookie的保存是对应域名的Domain,它不会将一个域名的cookie发送到另外几个域名

//存入cookie
HttpCookie cookie = new HttpCookie("message");
cookie.Value = "Hello world";
Response.Cookies.Add(cookie);
//取出cookie
string cookieValue = Request.Cookies["message"].Value;

表单隐藏域

Http中post请求会将表单数据发送到服务器,对一些表单的处理如需要状态保存可以写入隐藏域。优点:Post可以发送大量数据,局限性:通过表单的提交发送数据,注意用于一份表单的处理。
隐藏域
最简单的就是服务端生成表单时,添加一个<input type="hidden" id="Message" value="Hello world" />隐藏域,客户端会以post方式将数据发送的服务器,弊端:只能保存字符信息
ViewState
为了使隐藏域可以保存复杂的数据类型,涉及到一种序列化Serialize技术。将复杂的Object类型可序列号为二进制和XML, 逆操作可将二进制数组反序列化为对象数据。
Base64将二进制数字转化为字符,可保存到隐藏域

Person doloris = new Person() { Name = "Doloris", Age = 28 };
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
formatter.Serialize(ms, doloris);
byte[] content = ms.ToArray();
string base64 = Convert.ToBase64String(content);

在WebForm中通过实现IStateManager接口的StateBag写入隐藏域;如<input type="hidden" name="__Viewstate__" id="__viewstate__" value="数据" 使用的序列化器是ObjectStateFormatter

Person doloris = new Person() { Name = "Doloris", Age = 28 };
ObjectStateFormatter formatter = new ObjectStateFormatter();
string base64 = formatter.Serialize(doloris);

在页面PreRenderComplete事件中序列化保存到隐藏域,在InitComplete反序列化对控件赋值
ControlState
ControlState是对单个控件中的数据状态保存,因ViewState来回传输的数据量大,可能被禁止

服务端保存状态

将数据保存到服务端。服务端状态保持主要是SessionApplication,有很多将Cache也归为状态保持,我感觉不太恰当。

Application

Application是一个全局状态管理,使用时不用区分会话,所以数据全部保持在服务端。为防止并发操作一般使用Lock锁。

    Application.Lock();
    Application["online"] = 0;
    Application.UnLock();

Session

Session每个客户端将数据保存在服务端,服务端对每个客户端生成一个key发送到客户端,客户端通过发送key获取服务端保存的数据。
一般用于用户信息验证,用户登陆成功后写入Session,再次发送请求时发送Session服务端可得到用户的信息。通常客户端时通过Cookie保存,在禁止Cookie时会保存到URL中。

HttpContext状态

其实HttpContext并不属于状态,HttpApplication通过管道处理HttpContext数据。管道间传递自定义数据通过HttpContext.Items方式。

posted @ 2018-05-31 09:16  LoveTomato  阅读(184)  评论(0编辑  收藏  举报