Http是请求,响应的模型,服务器不会来读取浏览器的网页,只能够得到客户端提交过来的数据
当用户点击提交,服务器就知道"提交回来了"(PostBack)网页只有设定了name的input,textarea,select的value属性值才会被提交给服务器
非表单元素无法将值传递给服务器的如:要设置DIV的值,直接是不行的,可以通过隐藏字段实现,将隐藏字段的value与DIV的内容设置成一样然后当用户提交信息,服务器获得隐藏字段的值,并把值 替换掉网页所有的 value如果指定from 表单method属性为get,那么在 action=1.ashx?a=123的参数就会被删除
如如果指定为post,那么action中的参数就会被提交到服务器来Label版本的值存到了ViewState中,TextBox版本的不用存,因为TextBox就是Input,自己就会提交给服务器,不需要隐藏字段.
用于asp.net重写DIV文本自增(还要同时递增Label的宽度,注意Width的单位) Label1.Text = (Convert.ToInt32(Label1.Text)+1).ToString(); Label1.Width = new Unit(Label1.Width.Value + 10); 查看生成的源代码,ASP.net将所有隐藏内容统一放到了名字为__VIEWSTATE的隐藏字段中,使用序列化 算法将所有隐藏的内容放到一个字符串中,点击几次在使用ViewStateDecoder这个工具查看ViewState 内容,发现确实将这些改变的内容放到了ViewState中禁用ViewState的方法:在页面最上面 Page标签 加入 EnableViewstate="false",禁用ViewState以后
TextBox版本不受影响,DIV版本受影响,因为input的value不依靠ViewState(可以禁用单个控件) 禁用ViewState后并不是完全去掉ViewState,还会有一小段代码,如果想在页面中完全没有ViewState 那么在页面中就不能有 runat=server的form,如果Button等服务端控件没有放到runat=server的form 中,那么则是不用的回答ViewState原理的时候说:input版本(TextBox)自增和DIV版本(Label)的不同
--------- ViewState 使用:
// 在后台为 ViewState 赋值 this.ViewState["key"] = "004"; this.ViewState.Add("key2", 360); // 调用 ViewState Label1.Text = this.ViewState["key"].ToString();
只要有runat=server的form就会产生 _VIEWSTATE等,所以去掉form的runat=server,这样除了Repeater等少数控件之外服务端控件都没法使用,只能使用html标签。
这是为什么说"要求高的互联网项目不用服务端控件"1.HTTP协议是无状态的,不会记得上次和网页"发生了什么",如果要知道上一次的状态,
一个方法就是在对浏览器响应结束之前将状态信息保存到页面表单中,下次页面再向服务器发出请求的 时候带上这些状态信息,这样服务器就能根据这些状态信息还原上次的状态了 2.状态信息保存在隐藏字段中的缺点:加大网站的流量,降低访问速度,机密数据放到表单中会有数据欺骗等安全问题原因:HTTP是用的TCP协议,为了降低服务器的消耗,当服务器响应完客户端后,就立马段掉,所以无状态
ASP.NET保存状态有以下几种:
Application 当前应用程序(所有用户使用一个Application)
Session 当前会话(每个用户一个会话)Cookie 保存在客户端的ViewState 针对当前页面(每个页面有一个ViewState)一、Application 对象
Application是全局的,保存与操作都放在服务器端,任何人都能访问
使用 object 保存
this.Application["t1"] = TextBox1.Text;Application.Lock(); //锁定Application.UnLock(); //解锁可以在 Global.asax 中对网页的访问量,点击量 做一些统计
二、Cookie的使用
Cookie存在客户端
Cookie是和站点相关的,并且每次向服务器请求的时候除了发送表单参数外,还会将和站点相关的所有Cookie都提交给服务器,是强制性的,Cookie也是保存在浏览器端的,而且浏览器会在每次请求的时候都会把和这个站点相关的Cookie提交到服务器,并将服务端返回的Cookie更新回数据库,因此可以将信息保存Cookie中,然后在服务器端读取,修改.服务器返回数据除了普通的html数据以外,还会返回修改后的Cookie,浏览器把拿到的Cookie值更新本地浏览器的Cookie就可以设置:
Response.SetCookie(new HttpCookie("Color",TextBox1.Text));
或
Response.Cookies.Add(new HttpCookie("Size","22"));
读取:
Lable1.Text = Request.Cookies["Color"].Value;
扩展使用:
HttpCookie h1 = new HttpCookie("Color", TextBox1.Text); //创建一个Cookie对象 h1.Expires = DateTime.Now.AddHours(1); //设置过期时间,只能用DateTime格式h1.HttpOnly = true; //设置客户端是否能够访问脚本Response.SetCookie(h1); //设置CookieResponse.AppendCookie(); //追加Cookie
Cookie的缺点和表单一样,不能存储过多的信息.
网站优化案例:
网站的图片服务器要与主站域名不一样,降低Cookie流量的传输注意:图片,CSS,JS等静态文件,都是单独请求中如果一个网站有 多个图的话,本地又有那个网站的 cookie 的话,
那么访问时,请求HTML 有传一次 Cookie, 请求每张图片都要再传 cookie ,这样就浪费了。。如果设置 图片服务器的域名和 主站的不一样的话,当下载图片的时候就不会传 cookie 了,因为 cookie 是不可以跨域的!!三、Session原理
Session存放在服务器端,存放的是object类型
private int i = 0; //每次请求来了都会new一个新的实现了IHttpHandler接口的类"变量"的实例, 进行处理,用完了就GC掉,所以不会保持上次的值,所以不会自增private static int j = 0; // static不会被实例化,所有访问者都访问同一个J的实例, 仍然保存上次的值,所以会自增Cookie不能存储过多信息,如果想保存大量的数据,可以保存一个Guid到Cookie中,然后在服务器中建立一个以Guid为Key,复杂数据为Value全局Dictionary,static 字段对于不同用户也只有一份,因此用static实现多用户共享数据,代码如下:
public class sessionMgr //session管理页面{ private static IDictionary> data = new Dictionary >(); public static IDictionary GetSession(string sessionId) { if (data.ContainsKey(sessionId)) { return data[sessionId]; } else { IDictionary session = new Dictionary (); data[sessionId] = session; //为data增加value ,sessionId为KEY,session为value return session; } } } protected void Page_Load(object sender, EventArgs e) //加载事件 { if (Request.Cookies["MySessionId"] == null) //判断是否有MySessionId,没则增加 { string sessionId = Guid.NewGuid().ToString(); Response.SetCookie(new HttpCookie("MySessionId", sessionId)); } } protected void btus_Click(object sender, EventArgs e) //设置Session单击事件 { string sessionId = Request.Cookies["MySessionId"].Value; IDictionary session = sessionMgr.GetSession(sessionId); session["服务端的数据"] = DateTime.Now; //添加键值 } protected void butd_Click(object sender, EventArgs e) //读取Session单击事件 { string sessionId = Request.Cookies["MySessionId"].Value; IDictionary session = sessionMgr.GetSession(sessionId); butd.Text = Convert.ToString(session["服务端的数据"]); }
ASP.net已经内置了Session机制,把上面的例子用ASP.NetSession重写,
注意:不要放太多的对象到Session,Session会有超时销毁的机制可以看到Session机制并不是HTTP协议规定的,是ASP.NET实现的,现在PHP,JSP等大部分服务端技术都实现了Session,原理都差不多如果当用户禁用了 Session ,可以在 Web.conf 中的 <system.web>里面增加属性,使得将SeesionID保存到 URL 中,<sessionState cookieless="UseUri" />ASP.NET内置的 Session
Session["one"] = DateTime.Now; //设值Label1.Text =Convert.ToString(Session["one"]); //取值