客户端状态保持(cookie)重点
cookie:一小段文本,明文。存储在客户端的浏览器内存里面或者磁盘。cookie是跟网站相关,百度可以往客户端写cookie,sina也可写cookie,但是百度只能读取跟百度网站相关的cookie。
cookie会随着请求网站一块发送到后台(如果请求百度的时候,那么就把百度的cookie放到请求报文里面去,然后发送到后台。)
www.xxx.com
cookie可以设置一个Path来限制某个路径下面的页面才会把cookie发送到后台。
比如:请求图片,请求一个css、js,为了提高性能,可以通过 path设置页面的所在路径,来控制cookie的发送。
Cookie的域:浏览器往后台发送数据时候,要把cookie放到请求报文里面去,发送到后台。
那么有个问题:请求是子域的网页,那么主域的cookie会不会发送到后台呢?
答案:是的。一块发送。如果请求时主域页面,子域的cookie是不会发送到后台的。
如果子域想让请求主域页面的时候也一块发送到后台,设置当前Cookie的域为主域可以了。
cookie是通过响应报文的方式写到前台。最终写入Cookie是通过响应报文头来的
cookie有限制(大多数浏览器)
Cookie:是一个客户端状态保持机制,(网站的数据是存在客户端),与隐藏域与ViewState对象都属于这种客户端状态保持,Cookie中存储的是关于网站相关的文本字符串数据。Cookie的存储方式有两种,如果不指定过期时间,那么存储在客户端浏览器内存中,如果指定了过期时间,那么存储在客户端的磁盘上。Cookie是与具体的网站有关的,如果我们将Cookie设置了过期时间,那么当用户在指定时间内访问我们的网站,那么属于我们网站的Cookie数据会放在请求报文中发送过来,其它网站的Cookie不会发送。
【Cookie的创建】
CookieDemo.aspx.cs
//cookie创建
Response.Cookies["cp1"].Value = "itcast";
CookieDemo2.aspx.cs
//获取Cookie的值
if (Request.Cookies["cp1"] != null)
{
Response.Write(Request.Cookies["cp1"].Value);
}
CookieDemo.aspx.cs
//创建Cookie并且指定过期时间.
Response.Cookies["cp2"].Value = "laowang";
Response.Cookies["cp2"].Expires = DateTime.Now.AddDays(3);
//删除Cookie
Response.Cookies["cp2"].Expires = DateTime.Now.AddDays(-1);
CookieDemo.aspx.cs
//Cookie跨域(域名)
Response.Cookies["cp3"].Value = "laowang";
Response.Cookies["cp3"].Domain = "xxx.com";//设置主域的。
Response.Cookies["cp3"].Path = "/2019-2-5";
Response.Cookies["cp3"].Expires = DateTime.Now.AddDays(3);
CookieDemo.aspx.cs
//另外一种创建Cookie的方式。
HttpCookie cookie1 = new HttpCookie("cp4","sssss");
cookie1.Expires = DateTime.Now.AddDays(3);
Response.Cookies.Add(cookie1);
【使用Cookie记住登录用户名】
Login.aspx
<form id="form1" runat="server">
<div>
用户名:<input type="text" name="txtName" value="<%=LoginUserName %>"/><br />
密码:<input type="text" name="txtPwd" /><br />
<input type="submit" value="登录" />
</div>
</form>
Login.aspx.cs
public string LoginUserName{get;set;}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
string userName = Request.Form["txtName"];
//写到cookie中
Response.Cookies["userName"].Value = userName;
Response.Cookies["userName"].Expires = DateTime.Now.AddDays(7);
}
else
{
//读Cookie。
if (Request.Cookies["userName"] != null)
{
string name =Server.UrlDecode(Request.Cookies["userName"].Value);
LoginUserName = name;
Response.Cookies["userName"].Value = Server.UrlEncode(name);
Response.Cookies["userName"].Expires = DateTime.Now.AddDays(7);
}
}
}
【Cookie 的限制】
大多数浏览器支持最大为 4096 字节的 Cookie。
浏览器还限制站点可以在用户计算机上存储的 Cookie 的数量。大多数浏览器只允许每个站点存储 20 个 Cookie;如果试图存储更多 Cookie,则最旧的 Cookie 便会被丢弃。有些浏览器还会对它们将接受的来自所有站点的 Cookie 总数作出绝对限制,通常为 300 个。
【多值 Cookie】
Response.Cookies["userInfo"]["userName"] = "patrick";
Response.Cookies["userInfo"]["lastVisit"] = DateTime.Now.ToString();
Response.Cookies["userInfo"].Expires = DateTime.Now.AddDays(1);
HttpCookie aCookie = new HttpCookie("userInfo");
aCookie.Values["userName"] = "patrick";
aCookie.Values["lastVisit"] = DateTime.Now.ToString();
aCookie.Expires = DateTime.Now.AddDays(1);
Response.Cookies.Add(aCookie);
【读取Cookie】
if(Request.Cookies["userName"] != null)
Label1.Text = Server.HtmlEncode(Request.Cookies["userName"].Value);
if(Request.Cookies["userName"] != null)
{
HttpCookie aCookie = Request.Cookies["userName"];
Label1.Text = Server.HtmlEncode(aCookie.Value);
}
DateTime dt;
dt = DateTime.Parse(Request.Cookies["userInfo"]["lastVisit"]);
【修改Cookie】
不能直接修改 Cookie。更改 Cookie 的过程涉及创建一个具有新值的新 Cookie,然后将其发送到浏览器来覆盖客户端上的旧版本 Cookie。下面的代码示例演示如何更改存储用户对站点的访问次数的 Cookie 的值:
int counter;
if (Request.Cookies["counter"] == null)
counter = 0;
else
{
counter = int.Parse(Request.Cookies["counter"].Value);
}
counter++;
Response.Cookies["counter"].Value = counter.ToString();
Response.Cookies["counter"].Expires = DateTime.Now.AddDays(1);
【删除Cookie】
删除 Cookie(即从用户的硬盘中物理移除 Cookie)是修改 Cookie 的一种形式。由于 Cookie 在用户的计算机中,因此无法将其直接移除。但是,可以让浏览器来为您删除 Cookie。该技术是创建一个与要删除的 Cookie 同名的新 Cookie,并将该 Cookie 的到期日期设置为早于当前日期的某个日期。当浏览器检查 Cookie 的到期日期时,浏览器便会丢弃这个现已过期的 Cookie。下面的代码示例演示删除应用程序中所有可用 Cookie 的一种方法:
HttpCookie aCookie;
string cookieName;
int limit = Request.Cookies.Count;
for (int i=0; i<limit; i++)
{
cookieName = Request.Cookies[i].Name;
aCookie = new HttpCookie(cookieName);
aCookie.Expires = DateTime.Now.AddDays(-1);
Response.Cookies.Add(aCookie);
}
【Cookie的安全性】
Cookie 的安全性问题与从客户端获取数据的安全性问题类似。在应用程序中,Cookie 是另一种形式的用户输入,因此很容易被他们非法获取和利用。由于 Cookie 保存在用户自己的计算机上,因此,用户至少能看到您存储在 Cookie 中的数据。用户还可以在浏览器向您发送 Cookie 之前更改该 Cookie。
千万不要在 Cookie 中存储敏感信息,如用户名、密码、信用卡号等等。不要在 Cookie 中放置任何不应由用户掌握的内容,也不要放可能被其他窃取 Cookie 的人控制的内容。
【确定浏览器是否接受 Cookie】
用户可将其浏览器设置为拒绝接受 Cookie。在不能写入 Cookie 时不会引发任何错误。同样,浏览器也不向服务器发送有关其当前 Cookie 设置的任何信息。
【小栗子—自动登录】
UserLogin.aspx
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
<script type="text/javascript">
window.onload = function () {
var validateCode = document.getElementById("validateCode");
validateCode.onclick = function () {
document.getElementById("imgCode").src = "ValidateImageCode.ashx?d=" + new Date().getMilliseconds();
}
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
用户名:<input type="text" name="txtName" value="<%=UserName%>" /><br />
密码;<input type="password" name="txtPwd" /><br />
验证码:<input type="text" name="txtCode" /><img src="ValidateImageCode.ashx" id="imgCode" /> <a href="javascript:void(0)" id="validateCode"> 看不清</a><br />
<input type="submit" value="登录" />
<input type="checkbox" name="autoLogin" value="auto" />自动登录
<span style="font-size:14px;color:red"><%=Msg %></span>
</div>
</form>
</body>
UserLogin.aspx.cs
public string Msg { get; set; }
public string UserName { get; set; }
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
//string userName = Request.Form["txtName"];
//UserName = userName;
if (CheckValidateCode())//先判断验证码是否正确.
{
CheckUserInfo();
}
else
{
//验证码错误
Msg = "验证码错误!!";
}
}
else
{
//判断Cookie中的值。
CheckCookieInfo();
}
}
#region 判断用户名密码是否正确
protected void CheckUserInfo()
{
//获取用户输入的用户名和密码.
string userName = Request.Form["txtName"];
UserName = userName;
string userPwd = Request.Form["txtPwd"];
//校验用户名密码.
BLL.UserInfoService UserInfoService = new BLL.UserInfoService();
string msg = string.Empty;
UserInfo userInfo = null;
//判断用户名与密码
if (UserInfoService.ValidateUserInfo(userName, userPwd, out msg, out userInfo))
{
//判断用户是否选择了“自动登录”
if (!string.IsNullOrEmpty(Request.Form["autoLogin"]))//页面上如果有多个复选框时,只能将选中复选框的的值提交到服务端。
{
HttpCookie cookie1 = new HttpCookie("cp1",userName);
HttpCookie cookie2 = new HttpCookie("cp2", Common.WebCommon.GetMd5String(Common.WebCommon.GetMd5String(userPwd)));
cookie1.Expires = DateTime.Now.AddDays(7);
cookie2.Expires = DateTime.Now.AddDays(7);
Response.Cookies.Add(cookie1);
Response.Cookies.Add(cookie2);
}
Session["userInfo"] = userInfo;
Response.Redirect("UserInfoList.aspx");
}
else
{
Msg = msg;
}
}
#endregion
#region 校验Cookie信息.
protected void CheckCookieInfo()
{
if (Request.Cookies["cp1"] != null && Request.Cookies["cp2"] != null)
{
string userName = Request.Cookies["cp1"].Value;
string userPwd = Request.Cookies["cp2"].Value;
//校验
BLL.UserInfoService UserInfoService = new BLL.UserInfoService();
UserInfo userInfo=UserInfoService.GetUserInfo(userName);
if (userInfo != null)
{
//注意:在添加用户或注册用户时一定要将用户输入的密码加密以后在存储到数据库中。
if (userPwd == Common.WebCommon.GetMd5String(Common.WebCommon.GetMd5String(userInfo.UserPass)))
{
Session["userInfo"] = userInfo;
Response.Redirect("UserInfoList.aspx");
}
}
Response.Cookies["cp1"].Expires = DateTime.Now.AddDays(-1);
Response.Cookies["cp2"].Expires = DateTime.Now.AddDays(-1);
}
}
#endregion
#region 判断验证码是否正确
protected bool CheckValidateCode()
{
bool isSucess = false;
if (Session["validateCode"] != null)//在使用Session时一定要校验是否为空
{
string txtCode = Request.Form["txtCode"];//获取用户输入的验证码。
string sysCode = Session["validateCode"].ToString();
if (sysCode.Equals(txtCode, StringComparison.InvariantCultureIgnoreCase))
{
isSucess = true;
Session["validateCode"] = null;
}
}
return isSucess;
}
#endregion
WebCommon.cs
using System.Security.Cryptography;
namespace ZWH.ItcastProject.Common
{
public class WebCommon
{
/// <summary>
/// 对字符串进行MD5运算
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static string GetMd5String(string str)
{
MD5 md5 = MD5.Create();
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(str);
byte[] md5Buffer = md5.ComputeHash(buffer);
StringBuilder sb = new StringBuilder();
foreach (byte b in md5Buffer)
{
sb.Append(b.ToString("x2"));
}
return sb.ToString();
}
}
}
ZWH.ItcastProject.BLL
UserInfoService.cs
/// <summary>
/// 根据用户的名称,获取用户的信息
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public UserInfo GetUserInfo(string userName)
{
return userInfoDal.GetUserInfo(userName);
}
其他需要调用的方法,请看此博客。(忘记要放哪篇博客了T_T)