1. 程式人生 > 其它 >PHP網路技術(五)——cookie及記住使用者名稱功能實現

PHP網路技術(五)——cookie及記住使用者名稱功能實現

PHP網路技術(五)——cookie及記住使用者名稱功能實現

(原創內容,轉載請註明來源,謝謝)

Cookie是儲存在客戶端(主要是瀏覽器)的資訊,可以以此跟蹤和識別使用者。PHP無法直接操作Cookie,而是通過命令向瀏覽器傳送命令,由瀏覽器對Cookie進行操作。

一、PHP設定cookie方式

1)setcookie(name,value,expire,path,domain,secure,httponly)

第一個引數是必填的,後面都是選填的。

name是cookie的名稱,value不填則是空,value傳輸過程中會被使用urlencode進行轉碼。

expire是以秒計算的有效時間,如果有填的話則計時,瀏覽器關閉再開啟還在;如果沒填則計入記憶體,瀏覽器關閉再開啟就沒了。

path是有效路徑,domain是作用域名(如果設定的不對會導致重新整理或者重新開啟瀏覽器時無法獲取cookie),secure是加密傳輸(主要用於https)。

httponly如果是true則javascript無法操作此cookie,這有助於避免xss攻擊。

2)setrawcookie

引數和setcookie都一樣,區別在於value傳輸時不會被轉碼。

3)刪除cookie方式

將cookie的expire設定成過去時間即可。

二、cookie儲存機制

cookie通常用來儲存相對不敏感的資訊,例如記住使用者名稱密碼、登入控制等。由於cookie的儲存是瀏覽器進行的操作,因此不同瀏覽器的儲存機制也不相同。

1)儲存位置

IE在每個域名下面儲存一個文字檔案,用於記錄不同網站的cookie。Firefox將檔案都儲存在sqlite資料庫中進行管理,但是為了安全,Firefox4以上的版本對檔案進行了加密處理,只有特定的API才可以讀取檔案,其中儲存了id、cookie名、值、對應的host、路徑、失效時間、ishttponly等資訊。

2)有效時間

如果設定cookie時,有設定expire,則關閉瀏覽器後再次開啟瀏覽器,cookie還會存在。但是如果沒有設定expire,則會被存入瀏覽器的內容,當瀏覽器關閉時cookie失效。另外,還有通過flash建立的cookie,稱為flash shared object,其不受瀏覽器管理,即使瀏覽器清空資料仍會存在,只有格式化硬碟或者使用特定的軟體才能刪除。

3)數量限制

不同瀏覽器對每個域名下的cookie有所限制,IE8一個域名可以放50個cookie,firefox可以放150個。超過限制後,新的會把最舊的內容頂掉。

4)安全性

由於服務端和javascript都可以設定cookie,因此不夠安全,可以通過ishttponly設定不允許javascript進行操作。但是即便如此,由於cookie可以用軟體拼接進行傳送,因此仍不安全,保密的資訊不適合用cookie儲存,如果要儲存則必須進行加密。

5)佔用資源

cookie使用可以帶來好的使用者體驗,但是其佔用頻寬,由於客戶端和服務端的通訊都會帶上cookie,因此,每次http請求會來回傳送cookie共兩次,佔用上下行流量。因此不能濫用cookie,不要把cookie當作服務端的儲存器進行使用。

三、跨域與P3P協議

cookie只能在一個應用中使用,即一個cookie只能有建立它的應用獲得。但是如果一個專案有多個域名,需要實現跨域名獲取cookie,則需要使用p3p協議。

1)P3P

P3P協議是為web使用者提供對自己公開資訊的更多控制,支援此協議的站點未瀏覽者宣告他們的隱私策略。

P3P協議的使用,即要求共享某個cookie值的域名在cookie設定操作之前,加一個p3p的header頭,且定義哪些域名可以訪問該cookie,則被定義的域名可以直接獲得此域名下的cookie。

2)實現方式

假設公司有兩個域名,a.company.com和b.company.com,a域名需要共享某個cookie給b,方法如下。

a域名下的檔案:

         header(‘P3P:CP=”CURa AMDa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOIDSP COR”’);
         setcookie(‘cookiename’,’value’,time()+3600, ‘/’, ‘.b.company.com’);

b域名下的檔案:

         $_COOKIE[‘cookiename’];

3)注意事項

頁面cookie必須設定expire,否則無法生效;利用iframe時,需要在獲取的相應動態頁頭新增P3P的資訊,否則IE會把iframe的cookie阻止。

如果僅有兩個域名,此操作很方便,但是如果網站涉及很多的域名,則需要用完整的單點登入(SSO)方案,現有比較成熟的方案是CAS。

CAS有關的部落格如下。

http://www.coin163.com/java/cas/cas.html

http://www.cnblogs.com/lr393993507/p/5231432.html

四、本地儲存(localStorage)

設定cookie會佔用較多頻寬,且目前對每個域名下的cookie限制4kb。因此當有大量內容需要儲存在本地時,需要使用本地儲存技術,此技術使用javascript可以實現。

1)瀏覽器支援

用一段js程式碼可以判斷瀏覽器是否支援本地儲存:window.localStorage,如果是true則是支援,否則不支援。

2)增刪改查

a.新增方式較為靈活,有三種方式:

window.localStorage.key1 = ‘val1’ 或localStorage[‘key1’] = ‘val1’ localStorage.setItem(‘key1’, ‘val1’),當設定同樣的key時,後面的設定會覆蓋前面的設定。

另外,當不知道鍵名時,可以使用window.localStorage.key(i)獲取第i個鍵名,因此也可以相應的用鍵獲取值,可以用for迴圈獲取所有的鍵。

b. 獲取方式同樣靈活,也有三種對應的方式:

window.localStorage.key1 localStorage[‘key1’] ocalStorage.getItem(‘key1’)

c. 刪除分為刪除單個與全部刪除:

刪除單個採用localStorage.removeItem(‘key1’),全部刪除採用clear()方法。

d. 事件監聽

html5增加了對localStorage的事件監聽,包括onstorage、storage等事件。

3)其他注意事項

任何格式的儲存會被轉換成字串,因此如果需要儲存陣列等資訊時,可以先用json將內容轉換成特定格式的字串,在取出時在轉回去。

五、使用cookie實現記住使用者名稱

1)功能

使用cookie實現記住使用者名稱功能。

當每次重新重新整理或載入頁面,則去獲取cookie,如果存在則賦值給輸入框,如果不存在則將輸入框制空。

設定儲存使用者名稱按鈕,儲存2小時。關閉瀏覽器再次開啟仍然會存在。

設定取消儲存,再次重新整理則獲取到空。

2)頁面

a. 第一次開啟

b. 輸入使用者名稱,點選記住使用者名稱

c. 關閉瀏覽器,再次開啟瀏覽器,發現使用者名稱的cookie意見設定成功

d. 點選取消記住使用者名稱

e. 重新整理頁面,發現使用者名稱已經消失,關閉再次開啟瀏覽器同樣沒有

3)實現原始碼

a. 引入jquery-1.12.3.min.js

b. index.php 樣式頁面以及js頁面

<html>
         <head>
                   <title>記住使用者名稱</title>
                   <scripttype="text/javascript"src="jquery-1.12.3.min.js"></script>             
         </head>
         <body>
 使用者名稱:<inputid="username" />
                   <buttonid="btnSave">記住使用者名稱</button>
                   <buttonid="btnCancel">取消記住使用者名稱</button>
         </body>
</html>
<scripttype="text/javascript">
         $(function(){
                   //讀取頁面時獲取cookie
                   $.post("user.php",{type:'init'},function(result){
                            $("#username").val(result);
                   });    
                   //儲存使用者名稱到cookie
         $("#btnSave").click(function(){
                            var username =$('#username').val();
                            $.post("user.php",{type:'set',username:username},function(result){
                                     alert('設定成功');
                                     location=location;
                            });                       
         });
                   //取消儲存使用者名稱到cookie,即直接設定失效
         $("#btnCancel").click(function(){
                            $.post("user.php",{type:'unset'},function(result){
                                     alert('取消成功');
                                     location=location;
                            });                       
         });   
         });   
</script>
c. user.phpcookie處理頁面
<?php
//獲取型別
$type =$_POST['type'];
if('init'== $type){
         //初始化頁面,如果有內容則賦值,否則制空
         if(isset($_COOKIE['username'])){
                   echo $_COOKIE['username'];
         }else{
                   echo '';
         }
}elseif('set' == $type){
         //設定cookie
         $username = $_POST['username'];
         setcookie('username', $username,time()+36000, '/', '127.0.0.1', false, true);    
}else{
         //取消儲存使用者名稱到cookie,即直接設定失效
         setcookie('username', $username,time()-36000, '/', '127.0.0.1', false, true);     
}

4)注意事項

setcookie需要注意domain的設定,一開始domain我設定的不對,導致重新整理頁面一直沒有反應。並且在設定過程用firefox檢視本地cookie有設定。經過反覆除錯,發現domain設定的不對導致此結果。

——written by linhxx 2017.07.24