当前位置: 首页 > 文章教程  > 计算机与互联网 > 网络编程

11.3.1浏览器的Cookie设置

9/17/2020 9:37:07 PM 人评论

11.3.1浏览器的Cookie设置

11.3 Cookie会话技术

Cookie是一组“键值对”信息,该信息由WEB服务器的PHP程序生成,最终保存到浏览器内存甚至保存到浏览器端硬盘文件中。

11.3.1 浏览器的Cookie设置

一台主机中可以安装多种浏览器,每种浏览器默认情况下开启了Cookie,用户可以对浏览器进行设置决定是否开启Cookie。以IE浏览器为例,Cookie的设置方法如下。

打开IE浏览器后,单击“工具”菜单中的“Internet选项”选项,选择“隐私”选项卡,在“设置”区域拖动“滚动滑块”即可修改IE浏览器的Cookie配置。用户通常需要将“滚动滑块”拖动至“中”或“中高”,这样既可以保护隐私,又开启了Cookie,不影响某些网络功能的使用。

11.3.2 Cookie的工作原理

Cookie的工作原理如图11-2所示。

figure_0239_0303
图11-2 Cookie的工作原理

浏览器向某WEB服务器中的某页面(page1)发出第一次请求,page1页面接收到请求后创建Cookie,然后仅仅向浏览器返回一个Cookie响应头信息(Cookie响应头信息格式如图11-2所示)。Cookie 响应头信息中不包含任何需要显示的数据,只包含一些“键值对”信息。此时浏览器与WEB服务器之间完成了第一次请求与第一次响应。

浏览器接收到page1页面的Cookie响应头信息后,将根据自己Cookie的设置以及Cookie信息的过期时间,决定将Cookie信息以“键值对”的方式保存在浏览器端主机硬盘中,还是保存在浏览器进程使用的主机内存中。

当浏览器再次向同一 WEB 服务器其他页面(page2)发送第二次请求时,浏览器首先判断Cookie 信息是否失效,如果没有失效,浏览器会自动地将浏览器端的 Cookie 信息放入到第二次请求头中(Cookie请求头信息格式如图11-2所示)。page2页面接收第二次请求中的Cookie信息,从而实现同一WEB服务器内不同页面间的参数传递。

Cookie响应头“键值对”信息说明如下。

(1)Cookie响应头信息中的Set-Cookie关键字定义了该响应中包含了Cookie信息。

(2)name:指定Cookie的标记名称,为字符串类型数据。Cookie的标记名称由程序员定义,并由page1页面发送给浏览器,然后在浏览器端生成“键值对”信息中的“键”。

(3)value:指定 Cookie 的值,为字符串类型数据。Cookie 的值由程序员定义,并由 page1页面发送给浏览器,然后在浏览器端生成“键值对”信息中的“值”。

(4)expire:指定 Cookie 的过期时间,单位为秒,通常为整数数据,该整数数据是个 UNIX时间戳,即从UNIX纪元开始的秒数。

(5)path:指定 Cookie 在 WEB 服务器的有效路径。设定此值后,只有当浏览器访问 WEB服务器中有效路径下的页面时,浏览器才向请求头信息中加入Cookie信息。通过设置Cookie的有效路径,可以实现同一个WEB服务器下同一应用程序之间Cookie信息的安全性。

(6)domain:指定Cookie的有效域名。设定此值后,只有当浏览器访问该域名下的页面时,浏览器才会向请求头信息中放入 Cookie 信息。通过设置 Cookie 的有效路径,可以实现同一个WEB服务器下不同应用程序之间Cookie信息的安全性。

(7)secure:指定Cookie 信息通过HTTP 还是HTTPS 加入请求头中,取值范围为TRUE 或FALSE。默认值为FALSE,表示Cookie只有使用HTTP连接WEB服务器时,才将Cookie信息加入请求头中;值为TRUE时,表示Cookie只有使用HTTPS连接WEB服务器时,才将Cookie信息加入请求头中。

对于某个WEB服务器而言,该服务器的PHP程序关心的仅仅是Cookie的name属性和value属性,其他属性如path、domain和expire等仅仅是告诉浏览器如何处理这些Cookie。由于Cookie是将个人信息存放于浏览器端,因此在某种程度上降低了 WEB 服务器存储压力。但为此也增加了某些安全隐患,尤其是在一台计算机多个用户使用的场合下,容易将某个用户的个人信息暴露给其他用户。

figure_0240_0304只有浏览器端存在Cookie,并且该Cookie没有过期,domain和path匹配的情况下,该Cookie才有效,否则该Cookie失效。Cookie有效时,浏览器请求访问WEB服务器的其他页面时,才会将Cookie信息放入到请求头中。浏览器不会将Cookie信息放入到其他WEB服务器的请求头中,从而实现了Cookie信息跨服务器的安全性。

11.3.3 Cookie分类

按照Cookie的过期时间可以将Cookie分为会话Cookie和持久Cookie。

1.会话Cookie

图11-2中WEB服务器中的page1页面创建Cookie时,如果page1页面没有指定Cookie的过期时间或设置的Cookie过期时间为过去的时间(小于当前时间的UNIX时间戳),该Cookie为会话Cookie。会话Cookie的信息保存在当前浏览器进程使用的内存中,会话Cookie只在当前浏览器进程有效,关闭当前浏览器进程后,会话Cookie的信息从浏览器进程使用的内存中消失,会话Cookie将失效。会话Cookie的典型应用是实现Session会话技术。

2.持久Cookie

图11-2中WEB服务器中的page1页面创建Cookie时,如果page1页面指定Cookie的过期时间为未来的某个时间(大于当前时间的UNIX时间戳),并且浏览器开启了Cookie设置,该Cookie为持久 Cookie。持久 Cookie 的信息保存在浏览器端硬盘文件中,保存在浏览器端硬盘文件中的持久Cookie信息将一直有效,直到出现下面3种情况。

(1)当前时间的UNIX时间戳等于Cookie的过期时间。

(2)浏览器用户手动删除该持久Cookie。

(3)浏览器上的Cookie太多,超过了浏览器所允许的范围,浏览器将自动删除某些Cookie。因此若要实现两个单独的浏览器进程之间的信息共享,可以选择使用持久Cookie实现。持久Cookie 的典型应用是在 Cookie 的有效期内,打开浏览器时,浏览器自动填入用户名信息和密码信息,方便用户登录系统。

11.3.4 PHP使用Cookie的步骤

各种浏览器接收到Cookie响应头信息后,处理细节未必相同,这里以IE浏览器为例,阐述PHP使用Cookie的步骤(见图11-3)。

figure_0241_0305
图11-3 PHP使用Cookie的步骤

(1)浏览器第一次请求访问WEB服务器中的page1页面时,page1程序通过调用setcookie()函数或 header("Set-Cookie:name=value")函数创建 Cookie,产生 Cookie响应头信息,随着服务器的第一次响应将Cookie信息发送给浏览器。

(2)浏览器接收到含有Cookie响应头信息的响应后,判断该Cookie是会话Cookie还是持久Cookie。若是会话 Cookie,则将 Cookie 信息保存在浏览器进程中;若是持久 Cookie,浏览器会自动创建文本文件永久保存Cookie信息。

(3)当浏览器第二次请求该WEB服务器的page2页面时,浏览器判断Cookie是否过期以及domain和path是否匹配,然后再将Cookie信息封装到第二次请求中,向page2页面发出请求。page2页面通过使用预定义变量$_COOKIE访问到第二次请求头中的Cookie信息,从而实现page1页面与page2页面间的参数传递。

(4)浏览器关闭后,会话Cookie从内存中删除,而持久Cookie将保存在浏览器主机硬盘中。

figure_0241_0306WEB 服务器每次为浏览器返回一个响应(HTML 网页)的时候,这个响应由响应头信息和正文两部分组成。响应头中包含了一些“控制”信息,用于控制浏览器接下来的操作;正文部分包括可视的HTML数据、图片等信息。响应头总应该比正文部分先到达浏览器,以告知浏览器接下来的操作,WEB服务器若向浏览器发送正文信息,那么服务器应该首先发送响应头信息,以便控制浏览器如何处理正文信息。由于PHP的header()函数、setcookie()函数以及session_start()函数向响应中加入Cookie响应头信息,因此调用这些函数前不能有任何HTML数据的输出(包括空格),否则会提示“header already sent”错误信息。

防止提示“header already sent”错误信息的方法是设置 php.ini 文件中的配置选项output_buffering,将output_buffering设置为On。启用output_buffering后,在WEB服务器返回响应前,WEB服务器将所有响应头信息缓存到WEB服务器的缓存中,只有PHP程序中的所有语句执行完毕后,才将缓存中的响应头信息和内存中的执行结果(正文部分)发送给浏览器,避免了“header already sent”错误信息的出现。

11.3.5 创建Cookie

PHP提供的setcookie()函数是创建Cookie的最简单方法。

setcookie()函数的语法格式:

bool setcookie(string name[[[[, string value], int expire], string path],string domain], int secure])

函数功能:setcookie()函数中除了 name 参数外,其他参数都是可选的。setcookie()函数成功创建Cookie则返回TRUE,否则返回FALSE。例如程序create_cookie.php如下,该程序的运行结果如图11-4所示。

figure_0242_0307
图11-4 创建Cookie的示例程序运行结果

<?php

setcookie("myCookie", "Value of MyCookie");

setcookie("withExpire","expire in 1 hour",time()+60); //60秒=1分钟

setcookie("fullCookie","full cookie value",time()+60,"","",FALSE);

echo (time()+60);

?>

程序create_cookie.php说明:通常使用time()函数或mktime()函数加上秒数设定Cookie的过期时间。以time()函数为例,time()函数的语法格式为:int time ( void ),其功能是返回自从UNIX纪元(格林威治时间1970年1月1日00:00:00)到当前时间的秒数,也叫UNIX时间戳。

如果 IE 浏览器开启了 Cookie,浏览器接收到WEB服务器的响应后,会在浏览器端的主机硬盘中创建一个文件保存所有持久Cookie信息。以笔者的IE浏览器为例,在笔者主机的“C:\Documents and Settings\Administrator\Cookies”目录下创建一个administrator@11[2].txt文本文件,文件内容如图11-5所示。

figure_0242_0308
图11-5 Cookie文本信息

从图11-5中可以得知程序create_cookie.php创建了名字分别为withExpire和fullCookie的两个持久Cookie。而myCookie由于没有指定过期时间,仅仅是一个会话Cookie,会话Cookie并没有保存到文本文件中,关闭IE浏览器后,myCookie将立即失效,而withExpire和fullCookie在关闭浏览器的1min后失效。

figure_0242_0309程序create_cookie.php产生的withExpire和fullCookie的两个持久Cookie的有效路径为当前WEB服务器根目录下的“11”目录。

任何PHP程序产生的Cookie“键值对”中的“值”默认经urlencode()函数处理,例如程序create_cookie.php中将空格" "转换为加号“+”。

Cookie是HTTP协议头的一部分,用于浏览器和WEB服务器之间传递信息,建议在任何HTML内容输出到浏览器之前调用setcookie()函数(也不要有空格或空行),否则setcookie()函数可能创建Cookie失败。

11.3.6 预定义变量$_COOKIE

浏览器端产生Cookie信息后,再次向其他PHP页面发送请求时,WEB服务器会自动地收集请求头中的Cookie信息,并将这些Cookie信息解析到预定义变量$_COOKIE中。通过$_COOKIE可以读取所有通过HTTP请求传递的Cookie信息,$_COOKIE是一个全局数组,该数组中的每个元素的“键”为Cookie的标记名称,数组中每个元素的“值”为Cookie的值。例如,如下程序read_cookie.php的功能是创建并读取浏览器中的Cookie信息。

<?php

$time = time()+3600;

setcookie("name","victor",$time);

setcookie("password","1234567",$time);

if(isset($_COOKIE["name"])){

$name = $_COOKIE["name"];

echo $name;

echo "<br/>";

}else{

echo "HTTP请求头中没有名字为name的Cookie<br/>";

}

if(isset($_COOKIE["password"])){

$password = $_COOKIE["password"];

echo $password;

}else{

echo "HTTP请求头中没有名字为password的Cookie<br/>";

}

?>

打开浏览器后,第一次访问read_cookie.php的运行结果如图11-6所示。

figure_0243_0310
图11-6 $_COOKIE变量的使用

此时在浏览器端主机“C:\Documents and Settings\Administrator\Cookies”目录下创建一个 administrator@11[3].txt文本文件,文件内容如图11-7所示。

figure_0243_0311
图11-7 Cookie文本信息

刷新 read_cookie.php 页面或打开新的浏览器再次访问 read_cookie.php 页面后的运行结果如图11-8所示。读者可以自己分析两次访问同一个read_cookie.php页面产生不同结果的原因。程序read_cookie.php 将用户名和密码信息保存在了文本文件中,这无疑泄露了用户的隐私,有效的做法是使用md5加密算法将密码数据加密后保存在Cookie文本文件中。

figure_0243_0312
图11-8 $_COOKIE变量的使用

11.3.7 删除浏览器端的Cookie

浏览器端的 Cookie 可由浏览器用户根据需要手动删除,这可能给用户带来不好的用户体验。较好的做法是程序员开发PHP程序,让浏览器用户选择性地删除浏览器端的Cookie。使用PHP程序删除浏览器端的Cookie主要有两种方法:一种是将Cookie的值设置为空,另一种是将Cookie的有效时间设为过去的时间。不管使用哪种方法,浏览器接收到这样的 Cookie 响应头信息后,将自动删除浏览器端硬盘中的文本文件或内存中的 Cookie 信息。例如如下程序 destroy_cookie.php 的功能是将read_cookie.php程序创建的Cookie全部删除,使用浏览器访问该页面后,浏览器端“C:\Documents andSettings\Administrator\Cookies”目录中的administrator@11[3].txt文本文件将被删除。

<?php

$time = time()-3600;

setcookie("name","");

setcookie("password","1234567",$time);

?>

11.3.8 新闻发布系统用户管理功能的实现(一)

使用Cookie技术可以为“新闻发布系统”添加新的功能:将用户名和密码信息保存到浏览器端的Cookie文本文件中,下次打开登录页面时,无需再次输入用户名和密码。具体步骤如下。

(1)在“C:\wamp\www\news”目录下创建 login.php 程序,该程序实现的功能依次是:检查浏览器端是否存在有关用户登录的Cookie信息,若存在,将浏览器端Cookie中的用户名和密码信息取出;为浏览器用户提供登录表单,并填写Cookie中的用户名和密码信息。login.php页面中的代码如下。

<?php

$name = "";

if(isset($_COOKIE["name"])){

$name = $_COOKIE["name"];

}

$password = "";

if(isset($_COOKIE["password"])){

$password = $_COOKIE["password"];

}

?>

<form action="login_process.php" method="post">

用户名:<input type="text" name="name" size="11" value="<?php echo $name?>" /><br/>

密 码 :<input type="password" name="password" size="11" value="<?php echo $password?>"/><br/>

<input type="checkbox" name="expire" value="3600" checked/>Cookie保存1小时<br/>

<input type="submit" value="登录" />

</form>

(2)在“C:\wamp\www\news”目录下创建login_process.php文件,login_process.php程序实现的功能依次如下。

① 采集login.php页面中浏览器用户输入的用户名信息或自动填入的用户名信息。

② Cookie 文本文件中保存了账户信息,为了保证用户的账户信息安全地保存在浏览器端的Cookie文本文件中,Cookie文本文件中的密码是经md5加密后的数据。因此若从Cookie文本文件中获取密码信息,直接使用即可;若从login.php页面中的密码框中获取密码信息,需要将该密码md5加密。

③ 检查浏览器用户是否选择“Cookie 保存 1 小时”复选框。若没有选择该复选框, login_process.php程序调用setcookie()函数删除Cookie文本文件。

④ 再次使用 md5()函数加密密码,这是由于数据库 users 表中保存的是“admin”两次 md5加密后的数据。

⑤ 构造SQL语句,查询users表中是否存在该账户信息。若不存在,login_process.php程序将页面重定向到登录页面login.php,并传递“password_error”消息;若存在,检查浏览器用户是否选择“Cookie保存1小时”复选框,若选择了该复选框,login_process.php程序负责调用setcookie()函数将用户名和密码信息放置到Cookie文本文件中,然后将页面重定向到登录页面login.php,并传递“password_right”消息。

程序login_process.php代码如下。

<?php

include_once("functions/database.php");

$name = $_POST["name"];

if(isset($_COOKIE["password"])){

$first_password = $_COOKIE["password"];

}else{

$first_password = md5($_POST["password"]);

}

if(empty($_POST["expire"])){

setcookie("name",$name,time()-1);

setcookie("password",$first_password,time()-1);

}

$password = md5($first_password);

$sql = "select * from users where name='$name' and password ='$password'";

get_connection();

$result_set = mysql_query($sql);

if(mysql_num_rows($result_set)>0){

if(isset($_POST["expire"])){

$expire = time()+intval($_POST["expire"]);

setcookie("name",$name,$expire);

setcookie("password",$first_password,$expire);

}

header("Location:login.php?login_message=password_right");

}else{

header("Location:login.php?login_message=password_error");

}

close_connection();

?>

程序login_process.php的代码说明如下。

① 保存在数据库 users 表中的 password 字段值为 md5 两次加密后的数据,因此程序login_process.php需要使用两次md5加密算法将浏览器用户输入的密码信息加密,以便匹配数据库users表中的password字段值。

② 使用 GET 或 POST 提交方式提交的网页数据,全部封装为字符串类型提交到 WEB 服务器,因此必要时需要PHP程序使用数据类型转换函数进行类型转换。例如程序login_process.php调用intval()函数将字符串"3600"转换为整数3600。

③ 将login.php 程序修改为如下代码,使login.php 页面接收login_process.php 传递的查询字符串数据(字体加粗代码为新增代码,其他代码不变)。

<?php

if(isset($_GET["login_message"])){

if($_GET["login_message"]=="password_error"){

echo "密码错误,重新登录!<br/>";

}else if($_GET["login_message"]=="password_right"){

echo "登录成功!<br/>";

}

}

$name = "";

if(isset($_COOKIE["name"])){

$name = $_COOKIE["name"];

}

……

至此,通过使用Cookie实现了浏览器用户不必重新输入用户名和密码登录“新闻发布系统”的功能。

11.3.9 Cookie数组

使用setCookie()函数可以创建Cookie数组,语法格式如下:

setcookie(string name[下标], string value, int expire, string path,string domain, int secure)

figure_0246_0313创建Cookie数组时的name参数使用了下标,下标可以为整数或字符串,但下标两边不能用引号。此时可以为标记名称为name的Cookie设置多个Cookie值,这些Cookie值使用下标区分。

下面两个PHP程序,程序cookie_array.php负责创建Cookie数组,程序cookie_list.php负责读取Cookie数组中的值。

程序cookie_array.php

<?php

setcookie("name[1]","name1");

setcookie("name[2]","name2");

setcookie("name[one]","name one");

setcookie("name[two]","name two");

header("Location:cookie_list.php");

?>

程序cookie_list.php

<?php

foreach($_COOKIE["name"] as $key => $value){

echo $key,"=>",$value,"<br/>";

}

?>

figure_0247_0314创建Cookie数组时,不能直接使用setcookie()函数将数组作为该函数的第二个参数value,因为setcookie()函数的第二个参数value要求是一个字符串的值。

相关教程

共有条评论 网友评论

验证码: 看不清楚?