浅析http协议、cookies和session机制、浏览器缓存
最近几天在复习http协议中headers,cookies、session、缓存等相关知识,发现些新知识点。
这篇文章注重结合PHP去理解这些内容,也就是比较注重实践部分。
一、http headers
NO1:对于web应用,用户群在客户端 (各种浏览器)点击任何一个连接向服务器发送http请求,这过程肯定需要3次握手,建立连接,服务器响应返回数据。
每次请求都有头部和实体部分,先看下面笔者监听QQ空间的headers,QQ空间的原因是它头部内容比较全
Request Headers: GET http://user.qzone.qq.com/445235728 HTTP/1.1 Host: user.qzone.qq.com Connection: keep-alive Cache-Control: max-age=0 User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11 Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Referer: http://qzone.qq.com/ Accept-Encoding:gzip,deflate,sdch Accept-Language: zh-CN,zh;q=0.8 Accept-Charset: GBK,utf-8;q=0.7,*;q=0.3 Cookie:o_cookie=445235728;(省略很多……) If-Modified-Since: Wed, 13 Jun 2012 01:32:19 GMT ----------------- Response Headers: HTTP/1.1 200 OK Connection:close Server: QZHTTP-2.34.0 Date: Wed, 13 Jun 2012 02:59:31 GMT Content-Encoding: gzip Set-Cookie:login_time=61F0EEA02D704B1DBCF25166A74941B24F4BE24B205C466F;PATH=/; DOMAIN=qzone.qq.com Set-Cookie:Loading=Yes;expires=Wed,13-Jun-201216:00:00GMT;PATH=/;DOMAIN=qzone.qq.com X-UA-Compatible: IE=Edge Last-Modified: Wed, 13 Jun 2012 02:59:31 GMT Cache-Control: max-age=0, no-transform Content-Type: text/html;charset=utf-8 Transfer-Encoding: chunked
1、客户端请求headers包含了请求行和一些头域。
请求行:请求的方法 统一资源标识器(URL)协议版本 ------这三者用空格分开,最后换行回车(\r\n) 例如:GET http://user.qzone.qq.com/445235728 HTTP/1.1
各种头域:这些头域都是有关键字和键值成对组合,最后换行回车(\r\n)结束,这些头域告诉服务器应该怎么去响应以及本身一些信息。
2、服务器响应
状态行:协议版本 响应状态 状态描述 ------这三者用空格分开,最后换行回车(\r\n) 例如:HTTP/1.1 200 OK
各种头域:这些头域也是有关键字和键值成对组合,最后换行回车(\r\n)结束,这些头域告诉客户端应该怎么去响应以及本身一些信息。
NO2
这里就不一一说每个头域的概念和作用,想了解的请看:http://www.phpben.com/?post=34 现在介绍几个认为重要、在一些网站上的测试数据、以及请求返回各头域php代码实现
测试时间:2012.6.14前
测试对象:csdn 、cnbeta 、cnblos、腾讯(QQ空间、朋友网、新闻网)、新浪(微博、主页)、人人网、百度、淘宝、优酷、土豆这些网站
(1) Connection头域:这个头域只有http/1.1才有,默认是keep-alive值表示长连接,这样的话就不用每请求一个资源比如图片,css文件,js文件都要和服务器进行3此握手连接,这个在一定程度上弥补了http没状态的一个缺陷,减少连接服务器的时间。
查看测试网站Connection头域发现腾讯QQ空间、腾讯新闻网、新浪主页和微博,优酷和土豆Connection:close;除了这些其他的都是Connection:keep-alive
为什么?
1、connection: keep-alive 能正常使用的一个前提条件是还要提供content-length的头域告诉客户端正文的长度。那计算正文长度是个问题,对于多内容,集群服务器来说不是件易事。腾讯和新浪,优酷的这些都很难计算,对与工程师来说之间关闭了(默认是打开的)。
2、老服务器端不支持,对于腾讯,新浪这些老油条,服务器集群很庞大,难免有些老旧的不支持长连接的,为了一些兼容性问题,直接关闭了
Ps:这两点原因未求证过!^-^
用php headers(“Connection:keep-alive”);
(2) Content-Encoding头域
Content-Encoding文档的编码(Encode)方法.
上述网站出了cnbeta不用gzip压缩,优酷用deflate,其余都是。这也透漏一个重要信息,那就phper要掌握压缩gzip传输技术。
Php可以通过mod_gzip模块来实现。代码:ob_start("ob_gzhandler");
(3) Server头域暴漏服务器重要的安全信息。
Csdn:Server:nginx/0.7.68 ------------版本都暴露
腾讯QQ空间:Server:QZHTTP-2.34.0--------某位tx朋友透漏这是内部自己开发的服务器,这个可够安全
新浪微博:Server:apache -------------这个没暴漏版本
凤凰网:Server: nginx/0.8.53
人人网:Server:nginx/1.2.0
淘宝网:Tengine ---------这是淘宝内部技术团队开发的web服务器,基于Nginx
cnblogs博客园:Server:Microsoft-IIS/7.5
腾讯朋友网:Tencent/PWS ---------腾讯内部开发
腾讯新闻网:Server:squid/3.1.18
优酷网:Server: fswww1-----------是不是内部就不清楚,至少笔者不知道什么来的^_^
土豆网:Tengine/1.2.3
百度:server: BWS/1.0 ---------应该也是百度内部自己开发的服务器
很明显Server头域是返回服务器的信息,但也可以说暴漏信息,面对这个问题,大公司就自己开发基于自己功能的内部服务器。
(4) X-Powered-By头域可供修改,基于安全则可以修改
X-Powered-By头域反应什么语言什么版本执行后台程序。这个可以同个header函数修改
header("X-Powered-By:acb");
(5) Cache-control、expires、last-modified等重要头域
Cache-control:指定请求和响应遵循的缓存机制。在请求消息或响应消息中设置Cache-Control并不会修改另一个消息处理过程中的缓存处理过程。请求时的缓存指令包括no-cache、no-store、max-age、max-stale、min-fresh、only-if-cached,响应消息中的指令包括public、private、no-cache、no-store、no-transform、must-revalidate、proxy-revalidate、max-age。
Php代码实现:header("cache-control: abc");abc是上述指令值一个或多个,多个用’,’分开
Expires:告诉浏览器指明应该在什么时候认为文档已经过期,从而不再缓存它。代码实现:header("Expires:". date('D, d M Y H:i:s \G\M\T', time()+10));--------这个是把时间截转化成格林时区字符串给expires头域,这个显示时间会比中国北京时间少8个小时,东8区的实现:header("Expires:". date('r', time()+10))
last-modified:这个是服务器返回给浏览器,浏览器下次请求则把该值赋给if-modified-since头域传给服务器,服务器就可以根据此值判断是否有改变,有则继续运行下去,否者返回304 not modified。Php设置expires头域一样。
代码:
if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && (time()-strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) < 10)) { header("HTTP/1.1 304 Not Modified"); exit; } header("Last-Modified: " . date('D, d M Y H:i:s \G\M\T', time()) );或者header("Last-Modified: " . date('r', time()) );
前者是格林时间格式,后者是中国时间。需要注意的就是 php.ini 的时区 prc 则用后则,否者前者。笔者曾经试过在时区是 prc 的情况下用了前者,导致 time()-strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) <0 永远成立,因为是负值。
注意:当请求页面有session_start()的时候,则不管是否有expires、cache-control、last-modified设置,则返回给客户端Cache-Control头域为Cache-Control:no-store, no-cache, must-revalidate Expires头域 Expires:Thu, 19 Nov 1981 08:52:00 GMT。这个问题烦了笔者2天,都以为php.ini 或是apache的问题。最后竟然是session_start()的问题。
二、 浏览器缓存动态
前面介绍了http headers几个告诉浏览器如何处理缓存。但不同浏览器处理各种头域的方式不同,以下就是笔者。
Ps:各个浏览器监听http headers的方法可以查看:http://www.phpben.com/?post=76
(1) header(“cache-control: no-store”)
IE9
Google17.0
Firefox11
Maxthon3
点击刷新键
重发请求,返回200状态
重发请求,返回200状态
重发请求,返回200状态
重发请求,返回200状态
地址栏回车
重发请求,返回200状态
重发请求,返回200状态
重发请求,返回200状态
重发请求,返回200状态
点击后退键
同上
同上
同上
同上
(2) header(“cache-control: no-cache”)
IE9
Google17.0
Firefox11
Maxthon3
点击刷新键
重发请求,返回200状态
重发请求,返回200状态
重发请求,返回200状态
重发请求,返回200状态
地址栏回车
重发请求,返回200状态
重发请求,返回200状态
重发请求,返回200状态
重发请求,返回200状态
点击后退键
同上
From cache
From cache
同上
(3) header(“cache-control:bublic”)
IE9
Google17.0
Firefox11
Maxthon3
点击刷新键
重发请求,返回200状态
重发请求,返回200状态
重发请求,返回200状态
重发请求,返回200状态
地址栏回车
from cache
重发请求,返回200状态
重发请求,返回200状态
重发请求,返回200状态
点击后退键
From cache
From cache
From cache
同上
(4) header("cache-control:private"); header("cache-control: must-revalidate ")
IE9
Google17.0
Firefox11
Maxthon3
点击刷新键
重发请求,返回200状态
重发请求,返回200状态
重发请求,返回200状态
重发请求,返回200状态
地址栏回车
除第一次外都是from cache
重发请求,返回200状态
重发请求,返回200状态
重发请求,返回200状态
点击后退键
From cache
From cache
From cache
同上
(5) header("cache-control:max-age=num");num是秒数
IE9
Google17.0
Firefox11
Maxthon3
点击刷新键
重发请求,返回200状态
重发请求,返回200状态
重发请求,返回200状态
重发请求,返回200状态
地址栏回车
秒数 重发请求,返回200状态 重发请求,返回200状态 重发请求,返回200状态 点击后退键 From cache From cache From cache 同上 (6) IE9 Google17.0 Firefox11 Maxthon3 点击刷新键 重发请求,返回200状态 重发请求,返回200状态 重发请求,返回200状态 重发请求,返回200状态 地址栏回车 秒数 重发请求,返回200状态 重发请求,返回200状态 重发请求,返回200状态 点击后退键 From cache From cache From cache 同上 (7) IE9 Google17.0 Firefox11 Maxthon3 点击刷新键 秒数 秒数 秒数 重发请求,返回200状态 地址栏回车 from cache 秒数 秒数 重发请求,返回200状态 点击后退键 From cache From cache From cache 同上 结论: 1、 刷新对于任何浏览器且不管是什么cache-control,都会重新请求,一般返回是200,除非Last-Modified设置 2、 后退键除非no-cache; no-store外都是使用缓存 3、 Cache-control:no-store 在浏览器中任何操作都重新提交请求,包括后退 4、 遨游3的缓存很差 5、 IE9 的缓存很强,所以用ie9调试的时候尽可能点刷新而不是在地址栏回车 鉴于这种情况,对于不同的应用(有些要缓存,有些经常更新)对于不同的国家各种浏览器份额,而哪种缓存方式。中国IE比较多,加上360浏览器的加入(用IE内核),那就要主要参照IE浏览器。 但笔者还是比较喜欢header("Last-Modified: " . date('D, d M Y H:i:s \G\M\T', time()) );这种方式。结合起来connection:keep-alive能让缓存技术更成熟。 注意: 1、 也许你会问,用Cache-control:no-store或Cache-control:no-store,但调试页面还是没原来的缓存。然后清除浏览器缓存关掉重启浏览器, 缓存还在。这是因为你的web应用用了文件缓存如ecshop常出现这种情况,这种情况就要进web应用后台删除文件缓存。 2、 调试的时候尽可能不要在地址栏回车,特别是IE,google还好一点,但是要知道这次的测试只是各个浏览器中的一个版本,所以调试的时候尽可能点刷新按钮。 3、 但在cache-control:max-age=num 和expires 一起使用的时候,前者级别比较高,浏览器会忽略expires的设置。(上面没给出测试内容) Session 、cookies是程序员永远讨论的话题之一。 1、 简单说一下cookies、session (1) Cookies是保存在客户端的小段文本,随客户端点每一个请求发送该url下的所有cookies到服务器端。比如在谷歌浏览器下,打开ww.abc.com下的两个文件,a.php包含cookies1和cookies2,b.php包含了cookies3和cookies4,那么在a.php或b.php 点任意一个连接(当然是ww.abc.com服务器上的),浏览器就会把cookies1~4这4个cookies发送给服务器。但是如果在IE9有打开一个包含cookies5的c.php,哪门在google浏览器点击连接是不会发送cookies5的。 (2) Session则保存服务器段,通过唯一的值sessionID来区别每一个用户。SessionID随每个连接请求发送到服务器,服务器根据sessionID来识别客户端,再通过session 的key获取session值。SessionID传回服务器的实现方式可以通过cookies和url回写来实现。 注意: 1、 同一个浏览器打开同一个文件,如a.php ,或同时有设置session的两个文件a.php、b.php sessionID则只有一个。(时间上不能是打开a.php 关闭浏览器再打开b.php) 2、 不同浏览器在同一时间打开同意文件的sessionID也不一样 3、 sessionID是服务器生成的不规则唯一字符串,如: PHPSESSID=05dbfffd3453b7be02898fdca4fcd82b;------ PHPSESSID可以通过php.ini中session.name来改变,所以笔者在监听一些大型网站的时候查不出PHPSESSID,这是一个安全因素。 (3) cookies、session在php中的主要相关参数 (1) session.save_handler = ”files” 默认以文件方式存取session数据,如果想要使用自定义的处理器来存取session数据,比如数据库,用”user”。 (2) session.use_cookies = 1 前面说到sessionID用cookies来实现,这里就是,1表示用cookies (3) session.use_trans_sid = 0 上面是用cookies来实现sessionID,这里值若是1则使用url回写方式,级别比session.use_cookies高 (4) session.use_only_cookies = 0 值为1则sessionID只可以用cookies实现,级别比前两个高 (5) session.cache_expire =180 session 缓存过期的秒数 (6) session.gc_maxlifetime = 1440 设定保存的session文件生存期,超过此参数设定秒数后,保存的数据将被视为’垃圾’并由垃圾回收程序清理。判断标准是最后访问数据的时间(对于FAT文件系统是最后刷新数据的时间)。如果多个脚本共享同一个session.save_path目录但session.gc_maxlifetime不同,将以所有session.gc_maxlifetime指令中的最小值为准。 (4) 图说cookie 、ssession php代码如下 结论: 1、 第一次请求是没用cookies的,而第二次有PHPSESSID和两个cookies是因为服务器第一请求返回这个三个cookies。 2、第二次请求比第一次多返回PHPSESSID这个cookies,在第二次则没有了,直到session过期后重新设置。 2、 ;浏览器关掉cookies,session是否可以正常运行? 前面提及sessionID的时候有两种方式。 (1) cookies 方式,在session.use_trans_sid=0 and session.use_cookies = 1的情况下使用。这种方法是每次浏览器端点每个请求,都把sessionID发送到服务器。 (2) url回写,session.use_only_cookies = 0 and session.use_trans_sid=1的情况下,服务器会忽略session.use_trans_sid,在浏览器发hhtp请求后,服务器会在返回页面内容中每个连接后面加上PHPSESSID=05dbfffd3453b7be02898fdca4fcd82b (在php.ini没改session.name,默认是PHPSESSID),这样就算客户端的浏览器禁止了cookies,一样能实现session功能。 这里来个测试: 在1.php文件代码: 在 2.php 文件代码: 情景1:没禁用浏览器的cookies(用cookies实现session),则在2.php能正常输出 情景2:禁用用浏览器的cookies且在php.ini开启session.use_trans_sid=1,通过1.php第一连接过去显示不了session的值,但第二个连接则正常显示。(说明url回写正常运行)
header("Expires:". date('D, d M Y H:i:s \G\M\T', time()+num)); num是秒数
if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && (time()-strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) < num)) {
header("HTTP/1.1 304 Not Modified");
exit;
} header("Last-Modified: " . date('D, d M Y H:i:s \G\M\T', time()) );
三、 Session和cookies
session_start();
$_SESSION['favcolor'] = 'green';
$_SESSION['animal'] = 'cat';
$_SESSION['time'] = time();
setcookie("cookie1","www.scutephp.com",time()+3600*10);
setcookie("cookie2","www.scutephp.com",time()+3600*10);
echo 'Welcome to page #1<br/>';
session_start();
$_SESSION['favcolor'] = 'green';
$_SESSION['animal'] = 'cat';
$_SESSION['time'] = time();
// Works if session cookie was accepted
echo '<br /><a href="2.php">page 1 (这个href中没SID参数)</a><br/>';
// Or maybe pass along the session id, if needed
echo '<br /><a href="2.php?' . SID . '">page 2 (这个href中有SID参数)</a><br/>';
session_start();
echo 'Welcome to page #2<br />';
echo $_SESSION['favcolor'],'<br/>'; // green
echo $_SESSION['animal'],'<br/>'; // cat
echo date('Y m d H:i:s', $_SESSION['time']),'<br/>';
// You may want to use SID here, like we did in page1.php
echo '<br /><a href="1.php">return page 1</a>';

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











HTTP 상태 코드 520은 서버가 요청을 처리하는 동안 알 수 없는 오류가 발생하여 더 구체적인 정보를 제공할 수 없음을 의미합니다. 서버가 요청을 처리하는 동안 알 수 없는 오류가 발생했음을 나타내는 데 사용됩니다. 이는 서버 구성 문제, 네트워크 문제 또는 기타 알 수 없는 이유로 인해 발생할 수 있습니다. 이는 일반적으로 서버 구성 문제, 네트워크 문제, 서버 과부하 또는 코딩 오류로 인해 발생합니다. 상태 코드 520 오류가 발생하면 웹사이트 관리자나 기술 지원팀에 문의하여 자세한 정보와 지원을 받는 것이 가장 좋습니다.

HTTP 301 상태 코드의 의미 이해: 웹 페이지 리디렉션의 일반적인 응용 시나리오 인터넷의 급속한 발전으로 인해 사람들은 웹 페이지 상호 작용에 대한 요구 사항이 점점 더 높아지고 있습니다. 웹 디자인 분야에서 웹 페이지 리디렉션은 HTTP 301 상태 코드를 통해 구현되는 일반적이고 중요한 기술입니다. 이 기사에서는 HTTP 301 상태 코드의 의미와 웹 페이지 리디렉션의 일반적인 응용 프로그램 시나리오를 살펴봅니다. HTTP301 상태 코드는 영구 리디렉션(PermanentRedirect)을 나타냅니다. 서버가 클라이언트의 정보를 받을 때

NginxProxyManager를 사용하여 HTTP에서 HTTPS로의 자동 점프를 구현하는 방법 인터넷이 발전하면서 점점 더 많은 웹사이트가 HTTPS 프로토콜을 사용하여 데이터 전송을 암호화하여 데이터 보안과 사용자 개인 정보 보호를 향상시키기 시작했습니다. HTTPS 프로토콜에는 SSL 인증서 지원이 필요하므로 HTTPS 프로토콜 배포 시 특정 기술 지원이 필요합니다. Nginx는 강력하고 일반적으로 사용되는 HTTP 서버 및 역방향 프록시 서버이며 NginxProxy

HTTP 상태 코드 403은 서버가 클라이언트의 요청을 거부했음을 의미합니다. http 상태 코드 403에 대한 해결 방법은 다음과 같습니다. 1. 서버에 인증이 필요한 경우 올바른 자격 증명이 제공되었는지 확인합니다. 2. 서버가 IP 주소를 제한한 경우 클라이언트의 IP 주소가 제한되어 있거나 블랙리스트에 없습니다. 3. 파일 권한 설정을 확인하십시오. 403 상태 코드가 파일 또는 디렉토리의 권한 설정과 관련되어 있으면 클라이언트가 해당 파일 또는 디렉토리에 액세스할 수 있는 권한이 있는지 확인하십시오. 등.

해결 방법: 1. 요청 헤더에서 Content-Type을 확인합니다. 2. 요청 본문에서 데이터 형식을 확인합니다. 3. 적절한 인코딩 형식을 사용합니다. 4. 적절한 요청 방법을 사용합니다. 5. 서버측 지원을 확인합니다.

빠른 적용: PHP의 실제 개발 사례 분석 여러 파일의 비동기 HTTP 다운로드 인터넷의 발전으로 파일 다운로드 기능은 많은 웹 사이트와 응용 프로그램의 기본 요구 사항 중 하나가 되었습니다. 여러 파일을 동시에 다운로드해야 하는 시나리오의 경우 기존 동기 다운로드 방법은 비효율적이고 시간이 많이 걸리는 경우가 많습니다. 이러한 이유로 PHP를 사용하여 HTTP를 통해 여러 파일을 비동기적으로 다운로드하는 것이 점점 더 일반적인 솔루션이 되었습니다. 본 글에서는 실제 개발 사례를 통해 PHP 비동기 HTTP를 활용하는 방법을 자세히 분석해 보겠습니다.

C#의 일반적인 네트워크 통신 및 보안 문제와 해결 방법 오늘날 인터넷 시대에 네트워크 통신은 소프트웨어 개발에 없어서는 안 될 부분이 되었습니다. C#에서는 일반적으로 데이터 전송 보안, 네트워크 연결 안정성 등과 같은 일부 네트워크 통신 문제가 발생합니다. 이 문서에서는 C#의 일반적인 네트워크 통신 및 보안 문제에 대해 자세히 설명하고 해당 솔루션과 코드 예제를 제공합니다. 1. 네트워크 통신 문제 네트워크 연결 중단: 네트워크 통신 과정에서 네트워크 연결이 중단될 수 있으며, 이로 인해

C++에서 HTTP 스트리밍을 구현하는 방법은 무엇입니까? Boost.Asio 및 asiohttps 클라이언트 라이브러리를 사용하여 SSL 스트림 소켓을 생성합니다. 서버에 연결하고 HTTP 요청을 보냅니다. HTTP 응답 헤더를 수신하고 인쇄합니다. HTTP 응답 본문을 수신하여 인쇄합니다.
