怎样用cookie判断首次访问来判断用户初次访问网站的URL?

如何判断用户是否绕开登录直接访问系统内页面
[问题点数:60分]
本版专家分:0
结帖率 80%
CSDN今日推荐
本版专家分:0
结帖率 80%
本版专家分:7146
本版专家分:515
本版专家分:0
结帖率 80%
本版专家分:88361
2015年2月 总版技术专家分月排行榜第一2015年1月 总版技术专家分月排行榜第一
2015年3月 总版技术专家分月排行榜第二2014年12月 总版技术专家分月排行榜第二2014年9月 总版技术专家分月排行榜第二
2015年3月 .NET技术大版内专家分月排行榜第一2015年2月 .NET技术大版内专家分月排行榜第一2015年1月 .NET技术大版内专家分月排行榜第一2014年12月 .NET技术大版内专家分月排行榜第一2014年11月 .NET技术大版内专家分月排行榜第一
2015年7月 .NET技术大版内专家分月排行榜第二2015年6月 .NET技术大版内专家分月排行榜第二2015年5月 .NET技术大版内专家分月排行榜第二2014年10月 .NET技术大版内专家分月排行榜第二2014年9月 .NET技术大版内专家分月排行榜第二2014年8月 .NET技术大版内专家分月排行榜第二
本版专家分:88361
2015年2月 总版技术专家分月排行榜第一2015年1月 总版技术专家分月排行榜第一
2015年3月 总版技术专家分月排行榜第二2014年12月 总版技术专家分月排行榜第二2014年9月 总版技术专家分月排行榜第二
2015年3月 .NET技术大版内专家分月排行榜第一2015年2月 .NET技术大版内专家分月排行榜第一2015年1月 .NET技术大版内专家分月排行榜第一2014年12月 .NET技术大版内专家分月排行榜第一2014年11月 .NET技术大版内专家分月排行榜第一
2015年7月 .NET技术大版内专家分月排行榜第二2015年6月 .NET技术大版内专家分月排行榜第二2015年5月 .NET技术大版内专家分月排行榜第二2014年10月 .NET技术大版内专家分月排行榜第二2014年9月 .NET技术大版内专家分月排行榜第二2014年8月 .NET技术大版内专家分月排行榜第二
本版专家分:448827
2017年 总版技术专家分年内排行榜第十2013年 总版技术专家分年内排行榜第八
2017年2月 总版技术专家分月排行榜第三
2018年6月 .NET技术大版内专家分月排行榜第一2018年1月 .NET技术大版内专家分月排行榜第一2017年5月 .NET技术大版内专家分月排行榜第一2017年4月 .NET技术大版内专家分月排行榜第一2017年3月 .NET技术大版内专家分月排行榜第一2017年2月 .NET技术大版内专家分月排行榜第一2016年10月 .NET技术大版内专家分月排行榜第一2016年8月 .NET技术大版内专家分月排行榜第一2016年7月 .NET技术大版内专家分月排行榜第一
2018年4月 .NET技术大版内专家分月排行榜第二2018年3月 .NET技术大版内专家分月排行榜第二2017年12月 .NET技术大版内专家分月排行榜第二2017年9月 .NET技术大版内专家分月排行榜第二2017年7月 .NET技术大版内专家分月排行榜第二2017年6月 .NET技术大版内专家分月排行榜第二2016年12月 .NET技术大版内专家分月排行榜第二2016年9月 .NET技术大版内专家分月排行榜第二2016年6月 .NET技术大版内专家分月排行榜第二2016年3月 .NET技术大版内专家分月排行榜第二2016年1月 .NET技术大版内专家分月排行榜第二2015年12月 .NET技术大版内专家分月排行榜第二2015年2月 .NET技术大版内专家分月排行榜第二2015年1月 .NET技术大版内专家分月排行榜第二2014年11月 .NET技术大版内专家分月排行榜第二2014年5月 .NET技术大版内专家分月排行榜第二2014年4月 .NET技术大版内专家分月排行榜第二2012年2月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第二
本版专家分:448827
2017年 总版技术专家分年内排行榜第十2013年 总版技术专家分年内排行榜第八
2017年2月 总版技术专家分月排行榜第三
2018年6月 .NET技术大版内专家分月排行榜第一2018年1月 .NET技术大版内专家分月排行榜第一2017年5月 .NET技术大版内专家分月排行榜第一2017年4月 .NET技术大版内专家分月排行榜第一2017年3月 .NET技术大版内专家分月排行榜第一2017年2月 .NET技术大版内专家分月排行榜第一2016年10月 .NET技术大版内专家分月排行榜第一2016年8月 .NET技术大版内专家分月排行榜第一2016年7月 .NET技术大版内专家分月排行榜第一
2018年4月 .NET技术大版内专家分月排行榜第二2018年3月 .NET技术大版内专家分月排行榜第二2017年12月 .NET技术大版内专家分月排行榜第二2017年9月 .NET技术大版内专家分月排行榜第二2017年7月 .NET技术大版内专家分月排行榜第二2017年6月 .NET技术大版内专家分月排行榜第二2016年12月 .NET技术大版内专家分月排行榜第二2016年9月 .NET技术大版内专家分月排行榜第二2016年6月 .NET技术大版内专家分月排行榜第二2016年3月 .NET技术大版内专家分月排行榜第二2016年1月 .NET技术大版内专家分月排行榜第二2015年12月 .NET技术大版内专家分月排行榜第二2015年2月 .NET技术大版内专家分月排行榜第二2015年1月 .NET技术大版内专家分月排行榜第二2014年11月 .NET技术大版内专家分月排行榜第二2014年5月 .NET技术大版内专家分月排行榜第二2014年4月 .NET技术大版内专家分月排行榜第二2012年2月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第二
本版专家分:88361
2015年2月 总版技术专家分月排行榜第一2015年1月 总版技术专家分月排行榜第一
2015年3月 总版技术专家分月排行榜第二2014年12月 总版技术专家分月排行榜第二2014年9月 总版技术专家分月排行榜第二
2015年3月 .NET技术大版内专家分月排行榜第一2015年2月 .NET技术大版内专家分月排行榜第一2015年1月 .NET技术大版内专家分月排行榜第一2014年12月 .NET技术大版内专家分月排行榜第一2014年11月 .NET技术大版内专家分月排行榜第一
2015年7月 .NET技术大版内专家分月排行榜第二2015年6月 .NET技术大版内专家分月排行榜第二2015年5月 .NET技术大版内专家分月排行榜第二2014年10月 .NET技术大版内专家分月排行榜第二2014年9月 .NET技术大版内专家分月排行榜第二2014年8月 .NET技术大版内专家分月排行榜第二
本版专家分:1
本版专家分:1343
本版专家分:448827
2017年 总版技术专家分年内排行榜第十2013年 总版技术专家分年内排行榜第八
2017年2月 总版技术专家分月排行榜第三
2018年6月 .NET技术大版内专家分月排行榜第一2018年1月 .NET技术大版内专家分月排行榜第一2017年5月 .NET技术大版内专家分月排行榜第一2017年4月 .NET技术大版内专家分月排行榜第一2017年3月 .NET技术大版内专家分月排行榜第一2017年2月 .NET技术大版内专家分月排行榜第一2016年10月 .NET技术大版内专家分月排行榜第一2016年8月 .NET技术大版内专家分月排行榜第一2016年7月 .NET技术大版内专家分月排行榜第一
2018年4月 .NET技术大版内专家分月排行榜第二2018年3月 .NET技术大版内专家分月排行榜第二2017年12月 .NET技术大版内专家分月排行榜第二2017年9月 .NET技术大版内专家分月排行榜第二2017年7月 .NET技术大版内专家分月排行榜第二2017年6月 .NET技术大版内专家分月排行榜第二2016年12月 .NET技术大版内专家分月排行榜第二2016年9月 .NET技术大版内专家分月排行榜第二2016年6月 .NET技术大版内专家分月排行榜第二2016年3月 .NET技术大版内专家分月排行榜第二2016年1月 .NET技术大版内专家分月排行榜第二2015年12月 .NET技术大版内专家分月排行榜第二2015年2月 .NET技术大版内专家分月排行榜第二2015年1月 .NET技术大版内专家分月排行榜第二2014年11月 .NET技术大版内专家分月排行榜第二2014年5月 .NET技术大版内专家分月排行榜第二2014年4月 .NET技术大版内专家分月排行榜第二2012年2月 多媒体/设计/Flash/Silverlight 开发大版内专家分月排行榜第二
本版专家分:524
本版专家分:3120
本版专家分:3120
本版专家分:88361
2015年2月 总版技术专家分月排行榜第一2015年1月 总版技术专家分月排行榜第一
2015年3月 总版技术专家分月排行榜第二2014年12月 总版技术专家分月排行榜第二2014年9月 总版技术专家分月排行榜第二
2015年3月 .NET技术大版内专家分月排行榜第一2015年2月 .NET技术大版内专家分月排行榜第一2015年1月 .NET技术大版内专家分月排行榜第一2014年12月 .NET技术大版内专家分月排行榜第一2014年11月 .NET技术大版内专家分月排行榜第一
2015年7月 .NET技术大版内专家分月排行榜第二2015年6月 .NET技术大版内专家分月排行榜第二2015年5月 .NET技术大版内专家分月排行榜第二2014年10月 .NET技术大版内专家分月排行榜第二2014年9月 .NET技术大版内专家分月排行榜第二2014年8月 .NET技术大版内专家分月排行榜第二
匿名用户不能发表回复!|
CSDN今日推荐iOS 关于token、cookie的那些事 - 简书
iOS 关于token、cookie的那些事
cookie.jpg
关于 token
服务器如何判断当前用户是否登录?短连接(http:)使用token 机制来验证用户安全性,相信大多数App在用户登录后都是给用户自己认证的 token,当然也会在登录时重新分配 token ,作为用户的唯一凭证。把App比作游乐场的话,token 就相当于门票(私人订制的门票),只要你的门票没有失效,你就可以玩耍游乐园的任何你可以玩的项目。
token 值获取
当用户首次登录成功之后, 服务器端就会生成一个 token 值.
1.服务器会将 token 值保存在数据库中。并将这个 token 值返回给客户端.
2.客户端拿到 token 值之后,一般保存在两个位置,将 token 保存在沙盒中,作为一个公共参数传递.或者将 token 保存在 cookie 中。
如何使用 token
以后客户端再次发送网络请求(不是登录请求)的时候,就会将这个 token 值附带到参数中发送给服务器.服务器接收到客户端的请求之后,会取出 token 值与保存在本地(数据库)中的 token 值做对比,如果两个 token 值相同就说明用户登录成功过,当前用户处于登录状态。如果没有这个 token 值, 没有登录成功。如果 token 值不同,说明原来的登录信息已经失效,这时告诉客户端让用户重新登录。
关于 cookie
cookie 是服务端为了识别终端身份,保存在终端本地的用户凭证信息。cookie 中的字段与意义由服务端进行定义。例如,当用户在进行了登录操作后,服务端会将cookie 信息返回给终端,终端会将这些信息进行保存,在下一次再次访问服务端时,终端会将保存的cookie 信息一并发送到服务端,服务端根据cookie 信息是否有效来判断此用户是否可以进行一些行为。
token 和 cookie
既然 token 是用户的凭证信息,cookie 存储的是终端的用户凭证信息。那么 把 token 存在 cookie 中 ,服务器端就能准确够识别终端了。在客户端每次发起请求时就不用每次传 token 了,服务端从 cookie 中取就行。
在 iOS 中如何保存cookie
变成一条 cookie 存进去,iOS 中有关键的两个类 、,将信息交给 NSHTTPCookie ,变成可识别 cookie ,再存入 NSHTTPCookieStorage 中即可。
因为NSHTTPCookieStorage的默认策略是:NSHTTPCookieAcceptPolicyAlways。当你访问一个网站时,NSURLRequest都会帮你主动记录下来你访问的站点设置的Cookie,如果 Cookie 存在的话,会把这些信息放在 NSHTTPCookieStorage 容器中共享,当你下次再访问这个站点时,NSURLRequest会拿着上次保存下来了的Cookie继续去请求。
NSMutableDictionary*cookieProperties = [NSMutableDictionary dictionary];
[cookieProperties setObject:@"token"
forKey:NSHTTPCookieName]; //给cookie取名
NSString * token =[[NSUserDefaults standardUserDefaults] objectForKey:@"token"];
[cookieProperties setObject:token forKey:NSHTTPCookieValue];
[cookieProperties setObject:@"/" forKey:NSHTTPCookiePath]; //存放目录
NSString * domain = [NSURL URLWithString:@"http://www.baidu.com/"].
[cookieProperties setObject:domain forKey:NSHTTPCookieDomain]; //设置域名
NSHTTPCookie * httpCookie = [NSHTTPCookie cookieWithProperties:cookieProperties];
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:httpCookie]; //存入仓库
文末附 cookie 可以赋予的属性
在 iOS 中如何使用cookie
(1)一般在 App 启动时判断本地记录的值 该用户是否登录状态(即 token 为失效),如果是登录状态此时获取本地存取的 token 存为 cookie 。
(2)在登录完成时存 cookie 。
(3)在退出时清除 cookie 。
** 注:最好在 token 失效时和保存 cookie 前清除 cookie **
NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];
//删除token的那一条cookie
for (NSHTTPCookie *tempCookie in cookies)
if ([ isEqualToString:@"token"])
[cookieStorage deleteCookie:tempCookie];
附 : HTTP cookie的属性键
NSHTTPCookieName
Cookie的名字
NSHTTPCookieValue
Cookie的值
NSHTTPCookieOriginURL
和域名一样,NSHTTPCookieDomain或NSHTTPCookieOriginURL必须指定一个值
NSHTTPCookieVersion
接收器的版本。 0版本的地图“旧式”的Netscape的cookie。 版本1映射到RFC 2965的cookies
NSHTTPCookieDomain
NSHTTPCookiePath
Cookie 存放路径
NSHTTPCookieSecure
Cookie是否只应通过安全通道发送,设置Cookie的secure属性为true。只会在HTTPS和SSL等安全协议中传输此类Cookie。默认为false
NSHTTPCookieComment
包含Cookie的评论,只有有效的版本1的cookies或更高版本。 这头字段是可选的。
NSHTTPCookieCommentURL
接收器的评论URL。
NSHTTPCookieDiscard
Cookie是否应在会议结束时丢弃NSString,字符串值必须是“true”或“假”。 这个字段是可选的。 默认为“假”,除非这是Cookie是第1版或以上,NSHTTPCookieMaximumAge未指定,在这种情况下,它被假定为“TRUE” 。
NSHTTPCookieMaximumAge
NSString对象,包含一个整数,在Cookie内保持最多几秒 。仅适用于第1版和更高版本的有效。 默认为“0”。 此字段是可选的。
NSHTTPCookiePort
接收机的端口
//version: 0
name:token
value : token值
expiresDate:cookie有效截止日期
created :创建日期
sessionOnly: 返回接收器是否应该在会话结束时被丢弃 domain :域名
partition: 端口
isSecure:返回他的cookie不只应通过安全通道发送
&NSHTTPCookie version:0 name:"token" value:"b2a8fb4b9b2a79ff47c3f1" expiresDate:(null) created: 03:02:41 +0000 sessionOnly:TRUE domain:"api.test.com" partition:"none" path:"/" isSecure:FALSE&
如果你觉得对你有帮助请点喜欢哦,也可以关注 我,每周至少一篇技术。
每周至少5篇更新,多谢支持哈。
一位迷茫的iOS工程师。。。
保证每周一篇的更新量。。。
iOS App开发中的Cookie 一、何为Cookie Cookie是网站为了便是终端身份,保存在终端本地的用户凭证信息。Cookie中的字段与意义由服务端进行定义。例如,当用户在某个网站进行了登录操作后,服务端会将Cookie信息返回给终端,终端会将这些信息进行保存,在...
cookie机制 在程序中,会话跟踪是很重要的事情。理论上,一个用户的所有请求操作都应该属于同一个会话,而另一个用户的所有请求操作则应该属于另一个会话,二者不能混淆。例如,用户A在超市购买的任何商品都应该放在A的购物车内,不论是用户A什么时间购买的,这都是属于同一个会话的,...
摘要 Session 与 Cookie 不管是对 Java Web 的初学者还是熟练使用者来说都是一个令人头疼的问题。在初入职场时恐怕很多程序员在面试的时候都被问到过这个问题。其实这个问题回答起来既简单又复杂,简单是因为它们本身只是 HTTP 协议中的一个配置项,在 Ser...
时间:背景:在 iOS 开发中,大部分应用的用户登录机制都是基于 token 令牌的,我之前做过的项目也都是如此,但是在我现在的新项目中,由于服务端同学是沿用他们以前的 cookie 登录机制,所以我也不得不换种方式来对(zhe)待(teng)登(yi)...
作为深圳某高校的研究生,我的生活在同期学生中还是比较舒服的。其实我们研究生的生活是有保障的,首先每个月国家会有600块的补贴,据说今年会涨到800,然后如果你有自己所在实验室,那也会有相应的补贴,每个月400到800不等。你以为除此之外就完了?当然不是,因为研究生的时间远远...
伊索寓言:狼和小羊 狼来到小溪边,看见小羊正在那儿喝水。 于是狼就故意找碴儿说:“你把我喝的水弄脏了!你安的什么心?”
小羊吃了一惊,然后温和地说:“您站在上游,我在你的下游,怎么会把您喝的水弄脏呢?”
狼气冲冲地说:“就算这样吧,你总是个坏家伙!我听说去年你在背后里说...
今天在西安出差,西安在6月份经历过重组,办事处经理走了,主干业务走了,很多代理不做了。刚重组过得团队,在我看来应该会比较弱的,会出现人员不齐,心不齐,新兵多,渠道不健全。可恰恰相反。一走进办公室,迎面而来就是透露那种破釜沉舟的气势的鲜红横幅! 接触一天,你会发现办事处氛围活...
周四,是一周中最忙碌的一天了,又要跑早操,又要检查卫生,不过很忙碌,也很充实!
现在是晚上九点整,我和同学在体育馆打羽毛球,感觉运动真的很好!浑身热血沸腾,整个人也很舒服。
晚上泡泡脚,睡个好觉,开启新的一天!
赵凌彬,《护花高手在都市》中女主角乔小乔的饰演者。 她初次来到杭州汝来文化传播有限公司(《护花高手在都市》出品公司)试戏的时候,在场的出品人、总制片人、总策划、导演、编剧等人全都为之惊叹,继而会心的微笑挂在一众人的嘴角。 “这小妮子,真会演戏!”“她就是我心目中的乔小乔!”...php中如何同时使用session和cookie来保存用户登录信息
转载 &更新时间:日 11:31:47 & 作者:
本篇文章是对在php中同时使用session和cookie来保存用户登录信息的实现代码进行了详细的分析介绍,需要的朋友参考下
同时使用session和cookie来保存用户登录信息1、数据库连接配置页面:connectvars.php 代码如下:&?php//数据库的位置define('DB_HOST', '127.0.0.1');//用户名define('DB_USER', 'root');//口令define('DB_PASSWORD', '');//数据库名define('DB_NAME','test') ;?&2、登录页面:logIn.php 代码如下:&?php//插入连接数据库的相关信息require_once 'connectvars.php';//开启一个会话session_start();$error_msg = "";//如果用户未登录,即未设置$_SESSION['user_id']时,执行以下代码if(!isset($_SESSION['user_id'])){&&& if(isset($_POST['submit'])){//用户提交登录表单时执行如下代码&&&&&&& $dbc = mysqli_connect(DB_HOST,DB_USER,DB_PASSWORD,DB_NAME);&&&&&&& $user_username = mysqli_real_escape_string($dbc,trim($_POST['username']));&&&&&&& $user_password = mysqli_real_escape_string($dbc,trim($_POST['password']));&&&&&&& if(!empty($user_username)&&!empty($user_password)){&&&&&&&&&&& //MySql中的SHA()函数用于对字符串进行单向加密&&&&&&&&&&& $query = "SELECT user_id, username FROM mismatch_user WHERE username = '$user_username' AND "."password = SHA('$user_password')";&&&&&&&&&&& $data = mysqli_query($dbc,$query);&&&&&&&&&&& //用用户名和密码进行查询,若查到的记录正好为一条,则设置SESSION和COOKIE,同时进行页面重定向&&&&&&&&&&& if(mysqli_num_rows($data)==1){&&&&&&&&&&&&&&& $row = mysqli_fetch_array($data);&&&&&&&&&&&&&&& $_SESSION['user_id']=$row['user_id'];&&&&&&&&&&&&&&& $_SESSION['username']=$row['username'];&&&&&&&&&&&&&&& setcookie('user_id',$row['user_id'],time()+(60*60*24*30));&&&&&&&&&&&&&&& setcookie('username',$row['username'],time()+(60*60*24*30));&&&&&&&&&&&&&&& $home_url = 'loged.php';&&&&&&&&&&&&&&& header('Location: '.$home_url);&&&&&&&&&&& }else{//若查到的记录不对,则设置错误信息&&&&&&&&&&&&&&& $error_msg = 'Sorry, you must enter a valid username and password to log in.';&&&&&&&&&&& }&&&&&&& }else{&&&&&&&&&&& $error_msg = 'Sorry, you must enter a valid username and password to log in.';&&&&&&& }&&& }}else{//如果用户已经登录,则直接跳转到已经登录页面&&& $home_url = 'loged.php';&&& header('Location: '.$home_url);}?&&html&&&& &head&&&&&&&& &title&Mismatch - Log In&/title&&&&&&&& &link rel="stylesheet" type="text/css" href="style.css" /&&&& &/head&&&& &body&&&&&&&& &h3&Msimatch - Log In&/h3&&&&&&&& &!--通过$_SESSION['user_id']进行判断,如果用户未登录,则显示登录表单,让用户输入用户名和密码--&&&&&&&& &?php&&&&&&& if(!isset($_SESSION['user_id'])){&&&&&&&&&&& echo '&p class="error"&'.$error_msg.'&/p&';&&&&&&& ?&&&&&&&& &!-- $_SERVER['PHP_SELF']代表用户提交表单时,调用自身php文件 --&&&&&&&& &form method = "post" action="&?php echo $_SERVER['PHP_SELF'];?&"&&&&&&&&&&&& &fieldset&&&&&&&&&&&&&&&& &legend&Log In&/legend&&&&&&&&&&&&&&&& &label for="username"&Username:&/label&&&&&&&&&&&&&&&& &input type="text" id="username" name="username"&&&&&&&&&&&&&&& value="&?php if(!empty($user_username)) echo $user_ ?&" /&&&&&&&&&&&&&&&& &br/&&&&&&&&&&&&&&&& &label for="password"&Password:&/label&&&&&&&&&&&&&&&& &input type="password" id="password" name="password"/&&&&&&&&&&&& &/fieldset&&&&&&&&&&&& &input type="submit" value="Log In" name="submit"/&&&&&&&& &/form&&&&&&&& &?php&&&&&&& }&&&&&&& ?&&&& &/body&&/html&效果图:
3、登入页面:loged.php 代码如下:&?php//使用会话内存储的变量值之前必须先开启会话session_start();//如果会话没有被设置,查看是否设置了cookieif(!isset($_SESSION['user_id'])){&&& if(isset($_COOKIE['user_id'])&&isset($_COOKIE['username'])){&&&&&&& //用cookie给session赋值&&&&&&& $_SESSION['user_id']=$_COOKIE['user_id'];&&&&&&& $_SESSION['username']=$_COOKIE['username'];&&& }}//使用一个会话变量检查登录状态if(isset($_SESSION['username'])){&&& echo 'You are Logged as '.$_SESSION['username'].'&br/&';&&& echo '&a href="logOut.php"& Log Out('.$_SESSION['username'].')&/a&';}/**在已登录页面中,可以利用用户的session如$_SESSION['username']、&* $_SESSION['user_id']对数据库进行查询,可以做好多好多事情*/?&效果图:4、注销session与cookie页面:logOut.php(注销后重定向到lonIn.php) 代码如下:&?php/**同时注销session和cookie的页面*///即使是注销时,也必须首先开始会话才能访问会话变量session_start();//使用一个会话变量检查登录状态if(isset($_SESSION['user_id'])){&&& //要清除会话变量,将$_SESSION超级全局变量设置为一个空数组&&& $_SESSION = array();&&& //如果存在一个会话cookie,通过将到期时间设置为之前1个小时从而将其删除&&& if(isset($_COOKIE[session_name()])){&&&&&&& setcookie(session_name(),'',time()-3600);&&& }&&& //使用内置session_destroy()函数调用撤销会话&&& session_destroy();}//同时将各个cookie的到期时间设为过去的某个时间,使它们由系统删除,时间以秒为单位setcookie('user_id','',time()-3600);setcookie('username','',time()-3600);//location首部使浏览器重定向到另一个页面$home_url = 'logIn.php';header('Location:'.$home_url);?&
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具好好了解一下Cookie(强烈推荐) | WEB开发
好好了解一下Cookie(强烈推荐)
Cookie的诞生
由于HTTP协议是无状态的,而服务器端的业务必须是要有状态的。Cookie诞生的最初目的是为了存储web中的状态信息,以方便服务器端使用。比如判断用户是否是第一次访问网站。目前最新的规范是RFC 6265,它是一个由浏览器服务器共同协作实现的规范。
Cookie的处理分为:
服务器像客户端发送cookie
浏览器将cookie保存
之后每次http请求浏览器都会将cookie发送给服务器端
服务器端的发送与解析
发送cookie
服务器端像客户端发送Cookie是通过HTTP响应报文实现的,在Set-Cookie中设置需要像客户端发送的cookie,cookie格式如下:
Set-Cookie: "name=domain=.domain.path=/;expires=Sat, 11 Jun :42 GMT;HttpOsecure"
其中name=value是必选项,其它都是可选项。Cookie的主要构成如下:
name:一个唯一确定的cookie名称。通常来讲cookie的名称是不区分大小写的。
value:存储在cookie中的字符串值。最好为cookie的name和value进行url编码
domain:cookie对于哪个域是有效的。所有向该域发送的请求中都会包含这个cookie信息。这个值可以包含子域(如:
yq.aliyun.com),也可以不包含它(如:.aliyun.com,则对于aliyun.com的所有子域都有效).
path: 表示这个cookie影响到的路径,浏览器跟会根据这项配置,像指定域中匹配的路径发送cookie。
expires:失效时间,表示cookie何时应该被删除的时间戳(也就是,何时应该停止向服务器发送这个cookie)。如果不设置这个时间戳,浏览器会在页面关闭时即将删除所有cookie;不过也可以自己设置删除时间。这个值是GMT时间格式,如果客户端和服务器端时间不一致,使用expires就会存在偏差。
max-age: 与expires作用相同,用来告诉浏览器此cookie多久过期(单位是秒),而不是一个固定的时间点。正常情况下,max-age的优先级高于expires。
HttpOnly: 告知浏览器不允许通过脚本document.cookie去更改这个值,同样这个值在document.cookie中也不可见。但在http请求张仍然会携带这个cookie。注意这个值虽然在脚本中不可获取,但仍然在浏览器安装目录中以文件形式存在。这项设置通常在服务器端设置。
secure: 安全标志,指定后,只有在使用SSL链接时候才能发送到服务器,如果是http链接则不会传递该信息。就算设置了secure 属性也并不代表他人不能看到你机器本地保存的 cookie 信息,所以不要把重要信息放cookie就对了服务器端设置
cookie示例如下:
var http = require('http');
var fs = require('fs');
http.createServer(function(req, res) {
res.setHeader('status', '200 OK');
res.setHeader('Set-Cookie', 'isVisit=domain=.yourdomain.path=/;max-age=1000');
res.write('Hello World');
res.end();
}).listen(8888);
console.log('running localhost:8888')
直接设置Set-Cookie过于原始,我们可以对cookie的设置过程做如下封装:
var serilize = function(name, val, options) {
if (!name) {
throw new Error("coolie must have name");
var enc = encodeURIC
var parts = [];
val = (val !== null && val !== undefined) ? val.toString() : "";
options = options || {};
parts.push(enc(name) + "=" + enc(val));
// domain中必须包含两个点号
if (options.domain) {
parts.push("domain=" + options.domain);
if (options.path) {
parts.push("path=" + options.path);
// 如果不设置expires和max-age浏览器会在页面关闭时清空cookie
if (options.expires) {
parts.push("expires=" + options.expires.toGMTString());
if (options.maxAge && typeof options.maxAge === "number") {
parts.push("max-age=" + options.maxAge);
if (options.httpOnly) {
parts.push("HTTPOnly");
if (options.secure) {
parts.push("secure");
return parts.join(";");
需要注意的是,如果给cookie设置一个过去的时间,浏览器会立即删除该cookie;此外domain项必须有两个点,因此不能设置为localhost:
something that wasn't made clear to me here and totally confused me for a while was that domain names must contain at least two dots (.),hence 'localhost' is invalid and the browser will refuse to set the cookie!
服务器端解析cookie
cookie可以设置不同的域与路径,所以对于同一个name value,在不同域不同路径下是可以重复的,浏览器会按照与当前请求url或页面地址最佳匹配的顺序来排定先后顺序
所以当前端传递到服务器端的cookie有多个重复name value时,我们只需要最匹配的那个,也就是第一个。服务器端解析代码如下:
var parse = function(cstr) {
if (!cstr) {
var dec = decodeURIC
var cookies = {};
var parts = cstr.split(/s*;s*/g);
parts.forEach(function(p){
var pos = p.indexOf('=');
// name 与value存入cookie之前,必须经过编码
var name = pos & -1 ? dec(p.substr(0, pos)) :
var val = pos & -1 ? dec(p.substr(pos + 1)) :
//只需要拿到最匹配的那个
if (!cookies.hasOwnProperty(name)) {
cookies[name] =
}/* else if (!cookies[name] instanceof Array) {
cookies[name] = [cookies[name]].push(val);
cookies[name].push(val);
客户端的存取
浏览器将后台传递过来的cookie进行管理,并且允许开发者在JavaScript中使用document.cookie来存取cookie。但是这个接口使用起来非常蹩脚。它会因为使用它的方式不同而表现出不同的行为。
当用来获取属性值时,document.cookie返回当前页面可用的(根据cookie的域、路径、失效时间和安全设置)所有的字符串,字符串的格式如下:
"name1=value1;name2=value2;name3=value3";
当用来设置值的时候,document.cookie属性可设置为一个新的cookie字符串。这个字符串会被解释并添加到现有的cookie集合中。如:
document.cookie = "_fa=domain=.dojotoolkit.path=/"
设置document.cookie并不会覆盖cookie,除非设置的name value domain path都与一个已存在cookie重复。
由于cookie的读写非常不方便,我们可以自己封装一些函数来处理cookie,主要是针对cookie的添加、修改、删除。
var cookieUtils = {
get: function(name){
var cookieName=encodeURIComponent(name) + "=";
//只取得最匹配的name,value
var cookieStart = document.cookie.indexOf(cookieName);
var cookieValue =
if (cookieStart & -1) {
// 从cookieStart算起
var cookieEnd = document.cookie.indexOf(';', cookieStart);
//从=后面开始
if (cookieEnd & -1) {
cookieValue = decodeURIComponent(document.cookie.substring(cookieStart + cookieName.length, cookieEnd));
cookieValue = decodeURIComponent(document.cookie.substring(cookieStart + cookieName.length, document.cookie.length));
return cookieV
set: function(name, val, options) {
if (!name) {
throw new Error("coolie must have name");
var enc = encodeURIC
var parts = [];
val = (val !== null && val !== undefined) ? val.toString() : "";
options = options || {};
parts.push(enc(name) + "=" + enc(val));
// domain中必须包含两个点号
if (options.domain) {
parts.push("domain=" + options.domain);
if (options.path) {
parts.push("path=" + options.path);
// 如果不设置expires和max-age浏览器会在页面关闭时清空cookie
if (options.expires) {
parts.push("expires=" + options.expires.toGMTString());
if (options.maxAge && typeof options.maxAge === "number") {
parts.push("max-age=" + options.maxAge);
if (options.httpOnly) {
parts.push("HTTPOnly");
if (options.secure) {
parts.push("secure");
document.cookie = parts.join(";");
delete: function(name, options) {
options.expires = new Date(0);// 设置为过去日期
this.set(name, null, options);
通常所说的Web缓存指的是可以自动保存常见http请求副本的http设备。对于前端开发者来说,浏览器充当了重要角色。除此外常见的还有各种各样的代理服务器也可以做缓存。当Web请求到达缓存时,缓存从本地副本中提取这个副本内容而不需要经过服务器。这带来了以下优点:
缓存减少了冗余的数据传输,节省流量
缓存缓解了带宽瓶颈问题。不需要更多的带宽就能更快加载页面
缓存缓解了瞬间拥塞,降低了对原始服务器的要求。
缓存降低了距离延时, 因为从较远的地方加载页面会更慢一些。
缓存可以是单个用户专用的,也可以是多个用户共享的。专用缓存被称为私有缓存,共享的缓存被称为公有缓存。
私有缓存只针对专有用户,所以不需要很大空间,廉价。Web浏览器中有内建的私有缓存――大多数浏览器都会将常用资源缓存在你的个人电脑的磁盘和内存中。如Chrome浏览器的缓存存放位置就在:C:UsersYour_AccountAppDataLocalGoogleChromeUser DataDefault中的Cache文件夹和Media Cache文件夹。
公有缓存是特殊的共享代理服务器,被称为缓存代理服务器或代理缓存(反向代理的一种用途)。公有缓存会接受来自多个用户的访问,所以通过它能够更好的减少冗余流量。
下图中每个客户端都会重复的向服务器访问一个资源(此时还不在私有缓存中),这样它会多次访问服务器,增加服务器压力。而使用共享的公有缓存时,缓存只需要从服务器取一次,以后不用再经过服务器,能够显著减轻服务器压力。
事实上在实际应用中通常采用层次化的公有缓存,基本思想是在靠近客户端的地方使用小型廉价缓存,而更高层次中,则逐步采用更大、功能更强的缓存在装载多用户共享的资源。
缓存处理流程
而对于前端开发者来说,我们主要跟浏览器中的缓存打交道,所以上图流程简化为:
下面这张图展示了某一网站,对不同资源的请求结果,其中可以看到有的资源直接从缓存中读取,有的资源跟服务器进行了再验证,有的资源重新从服务器端获取。
注意,我们讨论的所有关于缓存资源的问题,都仅仅针对GET请求。而对于POST, DELETE, PUT这类行为性操作通常不做任何缓存
新鲜度限值
HTTP通过缓存将服务器资源的副本保留一段时间,这段时间称为新鲜度限值。这在一段时间内请求相同资源不会再通过服务器。HTTP协议中Cache-Control和 Expires可以用来设置新鲜度的限值,前者是HTTP1.1中新增的响应头,后者是HTTP1.0中的响应头。二者所做的事时都是相同的,但由于Cache-Control使用的是相对时间,而Expires可能存在客户端与服务器端时间不一样的问题,所以我们更倾向于选择Cache-Control。
Cache-Control
下面我们来看看Cache-Control都可以设置哪些属性值:
max-age(单位为s)指定设置缓存最大的有效时间,定义的是时间长短。当浏览器向服务器发送请求后,在max-age这段时间里浏览器就不会再向服务器发送请求了。
&meta http-equiv="Content-Type" content="text/ charset=utf-8"&
&meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /&
&meta http-equiv="X-UA-Compatible" content="IE=EDGE" /&
&title&Web Cache&/title&
&link rel="shortcut icon" href="./shortcut.png"&
&img src="./cache.png"&
var http = require('http');
var fs = require('fs');
http.createServer(function(req, res) {
if (req.url === '/' || req.url === '' || req.url === '/index.html') {
fs.readFile('./index.html', function(err, file) {
console.log(req.url)
//对主文档设置缓存,无效果
res.setHeader('Cache-Control', "no-cache, max-age=" + 5);
res.setHeader('Content-Type', 'text/html');
res.writeHead('200', "OK");
res.end(file);
if (req.url === '/cache.png') {
fs.readFile('./cache.png', function(err, file) {
res.setHeader('Cache-Control', "max-age=" + 5);//缓存五秒
res.setHeader('Content-Type', 'images/png');
res.writeHead('200', "Not Modified");
res.end(file);
}).listen(8888)
当在5秒内第二次访问页面时,浏览器会直接从缓存中取得资源
public 指定响应可以在代理缓存中被缓存,于是可以被多用户共享。如果没有明确指定private,则默认为public。
private 响应只能在私有缓存中被缓存,不能放在代理缓存上。对一些用户信息敏感的资源,通常需要设置为private。
no-cache 表示必须先与服务器确认资源是否被更改过(依靠If-None-Match和Etag),然后再决定是否使用本地缓存。
如果上文中关于cache.png的处理改成下面这样,则每次访问页面,浏览器都需要先去服务器端验证资源有没有被更改。
fs.readFile('./cache.png', function(err, file) {
console.log(req.headers);
console.log(req.url)
if (!req.headers['if-none-match']) {
res.setHeader('Cache-Control', "no-cache, max-age=" + 5);
res.setHeader('Content-Type', 'images/png');
res.setHeader('Etag', "ffff");
res.writeHead('200', "Not Modified");
res.end(file);
if (req.headers['if-none-match'] === 'ffff') {
res.writeHead('304', "Not Modified");
res.end();
res.setHeader('Cache-Control', "max-age=" + 5);
res.setHeader('Content-Type', 'images/png');
res.setHeader('Etag', "ffff");
res.writeHead('200', "Not Modified");
res.end(file);
no-store 绝对禁止缓存任何资源,也就是说每次用户请求资源时,都会向服务器发送一个请求,每次都会下载完整的资源。通常用于机密性资源。
关于Cache-Control的使用,见下面这张图(来自大额)
客户端的新鲜度限值
Cache-Control不仅仅可以在响应头中设置,还可以在请求头中设置。浏览器通过请求头中设置Cache-Control可以决定是否从缓存中读取资源。这也是为什么有时候点击浏览器刷新按钮和在地址栏回车,在NetWork模块中看到完全不同的结果
不推荐使用Expires,它指定的是具体的过期日期而不是秒数。因为很多服务器跟客户端存在时钟不一致的情况,所以最好还是使用Cache-Control.
服务器再验证
浏览器或代理缓存中缓存的资源过期了,并不意味着它和原始服务器上的资源有实际的差异,仅仅意味着到了要进行核对的时间了。这种情况被称为服务器再验证。
如果资源发生变化,则需要取得新的资源,并在缓存中替换旧资源。
如果资源没有发生变化,缓存只需要获取新的响应头,和一个新的过期时间,对缓存中的资源过期时间进行更新即可。
HTTP1.1推荐使用的验证方式是If-None-Match/Etag,在HTTP1.0中则使用If-Modified-Since/Last-Modified。
Etag与If-None-Match
根据实体内容生成一段hash字符串,标识资源的状态,由服务端产生。浏览器会将这串字符串传回服务器,验证资源是否已经修改,如果没有修改,过程如下(图片来自浅谈Web缓存):
上文的demo中我们见到过服务器端如何验证Etag:
由于Etag有服务器构造,所以在集群环境中一定要保证Etag的唯一性
If-Modified-Since与Last-Modified
这两个是HTTP1.0中用来验证资源是否过期的请求/响应头,这两个头部都是日期,验证过程与Etag类似,这里不详细介绍。使用这两个头部来验证资源是否更新时,存在以下问题:
有些文档资源周期性的被重写,但实际内容没有改变。此时文件元数据中会显示文件最近的修改日期与If-Modified-Since不相同,导致不必要的响应。
有些文档资源被修改了,但修改内容并不重要,不需要所有的缓存都更新(比如代码注释)
关于缓存的更新问题,请大家看看这里张云龙的回答,本文就不详细展开了。
本文demo代码如下:
&!DOCTYPE HTML&
&meta http-equiv="Content-Type" content="text/ charset=utf-8"&
&meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /&
&meta http-equiv="X-UA-Compatible" content="IE=EDGE" /&
&title&Web Cache&/title&
&link rel="shortcut icon" href="./shortcut.png"&
&img src="./cache.png"&
var http = require('http');
var fs = require('fs');
http.createServer(function(req, res) {
if (req.url === '/' || req.url === '' || req.url === '/index.html') {
fs.readFile('./index.html', function(err, file) {
console.log(req.url)
//对主文档设置缓存,无效果
res.setHeader('Cache-Control', "no-cache, max-age=" + 5);
res.setHeader('Content-Type', 'text/html');
res.writeHead('200', "OK");
res.end(file);
if (req.url === '/shortcut.png') {
fs.readFile('./shortcut.png', function(err, file) {
console.log(req.url)
res.setHeader('Content-Type', 'images/png');
res.writeHead('200', "OK");
res.end(file);
if (req.url === '/cache.png') {
fs.readFile('./cache.png', function(err, file) {
console.log(req.headers);
console.log(req.url)
if (!req.headers['if-none-match']) {
res.setHeader('Cache-Control', "max-age=" + 5);
res.setHeader('Content-Type', 'images/png');
res.setHeader('Etag', "ffff");
res.writeHead('200', "Not Modified");
res.end(file);
if (req.headers['if-none-match'] === 'ffff') {
res.writeHead('304', "Not Modified");
res.end();
res.setHeader('Cache-Control', "max-age=" + 5);
res.setHeader('Content-Type', 'images/png');
res.setHeader('Etag', "ffff");
res.writeHead('200', "Not Modified");
res.end(file);
}).listen(8888)
好了,本文关于cookie的介绍到此结束了,希望大家能够喜欢。

我要回帖

更多关于 cookie判断首次访问 的文章

 

随机推荐