初學者容易將cookie和session搞混淆,也有很多人簡單的把cookie和session簡單的理解爲一種爲客戶端存儲機制,另外一種爲服務端存儲機制。實際上cookie和session不僅是這麼簡單的,這一章就來詳細講解下關於cookie和session的內容。javascript
1 Cookie的基本概念和設置php
Cookie是一種存儲在客戶端的數據,能存儲cookie的客戶端不僅是瀏覽器,但絕大多數狀況下都是由瀏覽器來實現。瀏覽器經過http協議和服務端進行cookie交互。Cookie是獨立於語言而存在的,不少種語言均可以設置和讀取cookie。在實現過程當中,編程語言是經過指令通知瀏覽器,而後是瀏覽器實現設置cookie的功能的。而讀取cookie則是經過瀏覽器請求服務端時攜帶的http頭部中的cookie信息得來的。html
PHP中可以使用setcookie()來設置cookie,語法以下:java
bool setcookie ( string $name [, string $value = "" [, int $expire = 0 [, string $path = "" [, string $domain = "" [, bool $secure = false [, bool $httponly = false ]]]]]] )web
setcookie可定義cookie並將其隨http頭部一塊兒發送給客戶端,在設置cookie以前不能有任何輸出。當cookie被設置後,可在刷新頁面後經過$_COOKIE全局數組得到。sql
第一個參數name是必選參數,表示cookie的名稱,cookie的值是經過$_COOKIE[name]得到的。數據庫
第二個參數是設置的cookie的值,存儲在客戶端。編程
第三個參數是設置cookie的有效時間,以秒爲單位,若是想要刪除一個函數能夠將cookie的有效時間設置爲當前時間以前,或者使用unset($_COOKIE[name])來刪除某個cookie。若是不設置這個值,當瀏覽器關閉時,cookie會隨之失效。數組
參數path設置cookie的有效目錄,若是設置爲」/「則表示在當前目錄下都可用,若是設置爲」/foo/「則表示只有在目錄 「/foo/「 和其子目錄如」/foo/bar/「下才可。瀏覽器
參數domain設置cookie的做用域名,默認在本域名下有效。若是設置該值爲」Example Domain則改該域名下的全部子域名如i.e.w2.Example Domain均可使用該cookie。若是要設置一個域名的全部子域名均可使用,則設置其值爲如example.com便可。
參數secure用來設置是否對cookie進行加密傳輸,默認爲false。若是設置爲true,則只有在使用https的時候纔會設置cookie。
第七個參數若是爲true則表示只能經過http協議才能訪問該cookie,意味着客戶端javascript就不可操做這個cookie。使用此參數可減小XSS攻擊的風險。
下面使用PHP分別設置三個cookie:
<?php setcookie('name','chenxiaolong'); setcookie('num','100',time()+100,'/foo/'); setcookie(‘gender’,'male',time()+100,'','百度一下,你就知道'); print_r($_COOKIE); ?>
第一個cookie設置名爲name,值爲chenxiaolong ,其餘參數都是默認值,表示在當前目錄和域名下都有效,且有效時間持續到瀏覽器關閉。第二和第三個cookie的設置只在特定的目錄域名和有效時間內才能看到。注意當第一次在瀏覽器訪問這個腳本文件時,並不會有任何的輸出,由於設置完cookie後,須要刷新頁面在下次請求時http頭部纔會攜帶上一次設置的cookie信息,這時才能讀取到cookie。
第一次在瀏覽器訪問該腳本的請求消息頭(Request Headers)和響應消息頭(Response Headers)分別以下:
Request Headers: Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Encoding:gzip, deflate, sdch, br Accept-Language:zh-CN,zh;q=0.8 Cache-Control:max-age=0 Connection:keep-alive Host:localhost Upgrade-Insecure-Requests:1 User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36
可見其並無攜帶任何的cookie信息,說明瀏覽器並無向客戶端發送任何的cookie信息,而返回的響應消息頭中包含了cookie信息。
Response Headers: Connection:Keep-Alive Content-Length:10 Content-Type:text/html; charset=UTF-8 Date:Sun, 13 Nov 2016 08:48:14 GMT Keep-Alive:timeout=5, max=100 Server:Apache/2.4.16 (Unix) PHP/7.0.5 Set-Cookie:name=chenxiaolong Set-Cookie:num=100; expires=Sun, 13-Nov-2016 08:49:54 GMT; Max-Age=100; path=/foo/ Set-Cookie:gender=male; expires=Thu, 01-Jan-1970 00:00:10 GMT; Max-Age=-1479026884; domain=百度一下,你就知道 X-Powered-By:PHP/7.0.5
返回消息頭中包含三個 Set-Cookie 部分,這是通知瀏覽器設置對應的Cookie。當咱們再次刷新頁面的時候,可看到請求消息頭中攜帶了Cookie信息。刷新請求的獲得的請求消息頭以下:
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Encoding:gzip, deflate, sdch, br Accept-Language:zh-CN,zh;q=0.8 Cache-Control:max-age=0 Connection:keep-alive Cookie:name=chenxiaolong Host:localhost Upgrade-Insecure-Requests:1 User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36 Name
可見其中已經攜帶了Cookie信息,可是隻有設置的name這一個Cookie,這是由於其餘兩個Cookie不在這個目錄或本域名下有效。
咱們在前面已經講過,既然PHP和客戶端javascript均可以操做cookie,那麼用php設置的cookie也可用javascript讀取到,用javascript設置的cookie也可由php讀取到。不一樣的時,php設置的cookie須要在刷新頁面後的下一次請求中才有效,而javascript設置的cookie在本次請求中既有效。
以下用javascript代碼設置cookie:
<script type="text/javascript"> function setCookie(name,value) { var Days = 30; var exp = new Date(); exp.setTime(exp.getTime() + Days*24*60*60*1000); document.cookie = name + "="+ escape (value) + ";expires=" + exp.toGMTString(); } function getCookie(name) { var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)"); if(arr=document.cookie.match(reg)) return unescape(arr[2]); else return null; } setCookie('test','testhaha'); alert(getCookie('test')); </script>
瀏覽器訪問本頁用javascript設置的cookie會當即生效。咱們再來看訪問這個頁面的請求消息頭和響應消息頭,分別以下。
Request Headers: Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Encoding:gzip, deflate, sdch, br Accept-Language:zh-CN,zh;q=0.8 Cache-Control:max-age=0 Connection:keep-alive Cookie:test=testhaha Host:localhost Upgrade-Insecure-Requests:1 User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36
因爲使用的是javascript在客戶端設置的cookie,因此在本次向服務端發送http請求時就已經攜帶了cookie信息。咱們再用php代碼 echo $_COOKIE[‘test']; 來得到由javascript設置的cookie,此時可在頁面成功打印出名爲test的cookie的值。經過這個例子咱們更清晰的知道,cookie是由編程語言經過一些指令告知瀏覽器設置的,由瀏覽器實現,在瀏覽器和服務端進行通訊時,在http消息頭中攜帶cookie信息。
2 cookie的應用和存儲機制
Cookie常常用來存儲一些不敏感的信息,可用來防止刷票,記錄用戶名,限制重複提交等。
以防止用戶在一分鐘以內屢次提交爲例,代碼以下:
<script type="text/javascript">
function SetCookie(name, value) { var Days = 30; var exp = new Date(); exp.setTime(exp.getTime() + 60 * 100);//過時時間 1分鐘 document.cookie = name + "=" + escape(value) + ";expires=" + exp.toGMTString(); } function submit() { if(getCookie('submit')) { alert('you haved submited before,please submit after one minute'); } else { SetCookie('submit','yes'); } } function getCookie(name) { var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)"); if(arr=document.cookie.match(reg)) return unescape(arr[2]); else return null; } </script> <button onclick='submit()'>提交</button>
以上代碼實現的是防止用戶在一分鐘以內屢次提交表單,當用戶第一次提交表單時,設置cookie有效期爲1分鐘,當再次點擊提交時,判斷cookie是否過時來限制用戶的提交。
前面說,Cookie是存儲在客戶端的一段數據。可是不一樣的瀏覽器存儲Cookie的地方不一樣,一種是將Cookie數據保存在文件中,另外一種是保存在瀏覽器內存中。
在Windows系統上(這裏以Win7爲例)。IE瀏覽器Cookie數據位於%APPDATA%MicrosoftWindowsCookies 目錄中的xxx.txt文件 ,裏面可能有不少個.txt Cookie文件,如:C:Usersyren9AppDataRoamingMicrosoftWindowsCookies0WQ6YROK.txt
在IE瀏覽器中,IE將各個站點的Cookie分別保存爲一個XXX.txt這樣的純文本文件;而Firefox和Chrome是將全部的Cookie都保存在一個文件中,該文件的格式爲SQLite數據庫格式的文件。Firefox的Cookie數據位於:%APPDATA%MozillaFirefoxProfiles 目錄中的xxx.default目錄,名爲cookies.sqlite的文件。如:C:UsersjayAppDataRoamingMozillaFirefoxProfilesji4grfex.defaultcookies.sqlite
在Firefox中查看cookie, 能夠選擇」工具 > 選項 >」 「隱私 > 顯示cookie」。Chrome的Cookie數據位於:%LOCALAPPDATA%GoogleChromeUser DataDefault 目錄中,名爲Cookies的文件。如:C:UsersjayAppDataLocalGoogleChromeUser DataDefaultCookies 。
本文節選自 《php7實踐指南》 陳小龍著
微信掃一掃,發現更多內容