setcookie之前不能有任何的输出,比如echo,或是直接混编的HTML代码;
解决方法:
方法一:
在PHP里Cookie的使用是有一些限制的。
1、使用setcookie必须在<html>标签之前
2、使用setcookie之前,不可以使用echo输入内容
3、直到网页被加载完后,cookie才会出现
4、setcookie必须放到任何资料输出浏览器前,才送出
.....
由于上面的限制,解决办法是在输出内容之前,产生cookie,可以在程序的最上方加入函数 ob_start();
ob_start
:打开输出缓冲区
函数格式:void
ob_start(void)
说明:当缓冲区激活时,所有来自PHP程序的非文件头信息均不会发送,而是保存在内部缓冲区。为了输出缓冲区的内容,可以使用ob_end_flush()或flush()输出缓冲区的内容。
方法二:
解决Warning:
Cannot modify header information - headers already sent by ......
前几天装了个php的大头贴系统测试,发现报错Warning: Cannot modify header information - headers
already sent by ......
今天又装openads,还是出现这个问题。怒了。上网找了半天,有人说要在文件开头写上
ob_start();
失败。
后来打开
php.ini 然后把 output_buffering 设为 on 。重起appache,OK。看来这才是解决办法。
特别注意:
如果使用utf-8编码,一定要去掉UTF-8中的BOM,这都是因为utf-8编码文件含有的bom原因,而php4,5都是不支持bom的。去掉bom,可以用Notepad++打开转换一下。
http://m.blog.csdn.net/lamp_yang_3533/article/details/53083582
会话变量cookie和session是Web开发中必不可少的两个概念,不少人简单地把它们理解为一个是客户端的存储机制,一个是服务器端的存储机制,而没有理解其中的原理和特性。实际上,cookie和session之间存在复杂的关系,并没有想象中的那么简单。
随着Web应用的的普及,SSO单点登录的推广,有必要深刻认识cookie和session的一些基础知识。
1. Cookie的基本概念和设置
cookie是一种在远程浏览器端存储数据并以此跟踪和识别用户的机制。从实现上来说,cookie是存储在客户端上的一小段数据,浏览器(即客户端)通过HTTP协议和服务器端进行cookie交互。
注意:这里说的是客户端而不是浏览器,实际上能管理cookie的不仅仅是浏览器,当然最常见的是浏览器管理cookie,后面的叙述中不再区分这两个概念。
cookie独立于语言而存在,也就是说,不论是PHP还是JSP种下的cookie,其本质都是一样的,客户端脚本(如JavaScript)均能读取到。cookie在很多语言中都可以实现,严格地说,cookie并不是由这些语言实现的,而这些语言则是实现对cookie的间接操作,即发送HTTP指令,浏览器收到指令便操作cookie并返回给服务器。因此,cookie是由浏览器来实现和管理的。关于cookie的RFC文档主要有:RFC6265、RFC2109。
举例来说,我们经常使用PHP设置cookie,但实际上PHP并没有真正设置过cookie,甚至可以说,PHP根本就没有这个能力设置cookie。它只是发出命令让浏览器来做这件事而已,形象的说就是和“有关部门”打个招呼。
cookie主要是参照RFC2109标准由客户端实现其生成、使用等整个管理过程,服务器端则参照此标准实现和客户端之间的交互指令。
在PHP中使用setcookie()函数设置cookie,函数原型如下:
setcookie ( string $name [, string $value [, int $expire = 0 [,
string $path [, string $domain [, bool $secure = false [, bool $httponly = false ]]]]]] )
第一个参数是必选参数,设置cookie的名称。
第二个参数,设置cookie的值。参数为空时,cookie的值为空。由于把cookie的值设为false时,会使客户端尝试删除这个cookie,所以要在cookie上保存true或false时不应该直接使用布尔值,而应该使用1表示true,0表示false。
第三个参数,设置cookie的过期时间,时间戳的形式。如果设置为0或者不设置,表示浏览器关闭后,cookie失效。默认值为0。这个值很重要,它决定了cookie的存储方式,后面会详细讲解。
第四个参数,设置cookie的起作用路径。默认值为 "/" ,即在域名目录及目录下的所有子目录都生效。如果有需要,可以设置仅在某个目录下生效。
第五个参数,设置cookie的作用域名,默认在本域名下。
第六个参数,设置是否对cookie进行加密传输,默认为false。如果设置为true,只有使用https,这个cookie才会被设置。所以,通常情况下不设置此参数或使用默认值false。
第七个参数,表示是否只使用http访问cookie。如果为true,客户端的JavaScript就无法操作这个cookie。使用此参数可以减少XSS攻击的风险,但注意,不是所有的浏览器都支持这个参数。(再次强调,cookie和PHP没有任何关系,只和浏览器相关,PHP只负责跟浏览器打招呼,具体的管理由客户端浏览器完成。)
提示:setrawcookie函数和setcookie函数的功能基本一样,唯一的区别是setrawcookie不会对cookie的value进行urlencode转码。
注意:用PHP在当前页面设置的cookie不能立即生效,要等到下一个页面才能看到。这是由于设置的这个页面里的cookie有服务器传递给客户端浏览器,在下一个页面浏览器才能把cookie从客户端中取出传回服务器。如果是JavaScript设置的,是立即生效的。
cookie没有显示的删除函数。如果想删除cookie,可以将cookie的expire时间设置为已过期的时间,如1小时前,这会自动触发浏览器的删除机制。
如:setcookie ( "isLogin" , 1 , time() - 3600 );
如果对HTTP协议比较清楚,就知道cookie是HTTP头的一部分,即先发送或请求cookie,然后才是data域。因此,setcookie函数必须在其输出数据之前调用,这和header函数是相同的。不过,也可以使用输出缓冲函数延迟脚本的输出,直到设置好所有的cookie和其他的HTTP头。
2. cookie的存储机制及应用
cookie通常用来存储一些不是很敏感的信息,或者进行登录控制,也可用来记住用户名、记住免密码登录、防止刷票等。
如果将setcookie的最后一个参数httponly设置为true,JavaScript就无法读取到这个cookie,当然也可以在php.ini中设置这个参数。
有时,这样做能够增强网站的安全性。原理就是通知浏览器给cookie加上一个特殊参数,屏蔽JavaScript脚本的读取,通过其他方法还是能看到的。前面也谈到,如果浏览器不支持,即使设置了httponly,客户端JavaScript也可能读取到。
每个域名下允许的cookie数目是有限制的,根据浏览器的不同这个限制也不同。并且,一个cookie的最大字节数为4097(随着浏览器的升级,这个上限可能会增加)。
cookie的中文译名为“小甜饼或点心”,虽然cookie确实可以给我们带来许多好的用户体验,但cookie不是越多越好,它会增加带宽。也不要把cookie当作客户端的存储器来使用。
前面说过,cookie是保存在客户端的一段数据,那它究竟保存在什么地方呢?有两种情况:一种是保存在文件中,一种是保存在浏览器的内存中。
如果没有设置cookie的过期时间,cookie是默认保存在浏览器内存中的;反之,则是保存在客户机的磁盘文件中。不同的浏览器对cookie的管理策略都不相同,这里不做赘述。
还有一种cookie是Flash创建的,称为Flash Shard Object,又称Flash Cookie,即使清空浏览器所有的隐私数据,这类顽固的cookie可能还会存在硬盘上。因为它不受浏览器管理,只受Flash管理。很多网站采用这种技术识别用户。
3. cookie跨域与P3P协议
一般来说,cookie只能在一个应用中共享,即一个cookie只能由创建它的应用获得。实现cookie的跨域,主要是为了统一应用平台,即实现目前最流行的单点登录。最简单的方式是使用P3P协议。
P3P(Platform for Privacy Preferences)协议由万维网协会研制,为Web用户提供了对自己公开信息的更多控制。支持P3P协议的浏览器将Web站点策略与用户隐私偏好进行对比,并为用户提出不匹配的警告,通知用户有关Web隐私的处理方式。
cookie的跨域涉及两个不同的应用,习惯上称为第一方和第三方。
第一方cookie来自当前正在查看的网站,或者发送到当前正在查看的网站。
第三方cookie来自当前正在查看的网站之外的网站,或者发送到当前正在查看的网站之外的网站。
第三方网站通常提供正在查看的网站上的内容。例如,许多站点使用来自第三方网站的广告,或者IFRAME的别的网站的URL,这些第三方网站可能使用的cookie。
通过P3P使用户自己可以指定浏览器的隐私策略,达到存取第三方cookie的目的。你也许会觉得这跟Web应用毫无关系,真正的问题是如何让服务器指定用户浏览器的隐私策略,这就是P3P的使命,只要在响应用户请求时,在HTTP的头信息中增加关于P3P的配置信息就可以了,步骤如下:
(1)编辑hosts文件,加入测试域名
C:\Windows\System32\drivers\etc\hosts
127.0.0.1 www.atest.com
127.0.0.1 www.btest.com
(2)访问www.atest.com时,调用www.btest.com的页面,种下cookie
<script src="http://www.btest.com/t/get.php?id=100"></scipt>
在get.php文件中使用P3P种下本域名的cookie,代码如下:
<?php
header('P3P:CP="CURa ADMa-dEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NO|DSP COR"');
setcookie("p3p", $_GET['id'], time()+3600, "/", ".btest.com");
?>
之后,就可以在btest域,获取到设置的cookie了。
注意:
页面的cookie不能是浏览器进程的cookie,必须给cookie设置过期时间,否则跨域会获取不到。
利用IFRAME时,记得要在相应的动态页的页头添加P3P的信息,否则IE会把IFRAME框里的cookie给阻止掉,就会出现问题。
IE浏览器对跨域访问cookie限制比较严格,在Firefox、Chrome等浏览器下测试,即使不发送P3P头信息也能成功。
在实际应用中,如果仅仅有两个域名,很方便互相操作对方的cookie。如果是对个应用,其直接的关系就变得非常复杂了。这时,就需要一个完整的SSO方案,通常是通过一个SSO Server系统进行中转。CAS就是一个比较成熟的SSO解决方案。