在寫小程序時用的是自己新寫的框架,為了不重復性請求用戶信息所以將數據存到了session中(當然也可以redis)。
但是,在調試小程序時卻始終獲取不到session數據,因為是新框架、新環境,所以第一時間懷疑是環境問題。
耐心調試開始解決問題:
1.代碼已經開啟了session。
session_start();
2.查看phpinfo()中是否含有session模塊。
3.檢查session在配置文件、phpinfo中是否開啟(php中默認是不會開啟session的)
session.auto_start=0;//沒開啟
//phpinfo中模塊為off
注意,如果配置文件中session.auto_start=1,同時代碼中也執行了session_start時,這樣會造成session_id不一致,后果就是獲取不到想要的session值!!!。
4.vim修改session.auto_stat = 1后再查看php.ini,session.auto_start為on,開啟完畢
注意,這樣設置代碼中就不需要執行session_start(),因為后台配置已經自動開啟了,所以代碼已經開啟的前提下,這里再開啟會重新生成id,除非你代碼開啟前有輸出。
5.重啟php-fpm,測試,還是沒有數據。
6.檢查緩存文件夾。注意,有的時候因為路徑問題查看php.ini的路徑配置不一定正確哦。所以,直接查看phpinfo中save_path是否有設置緩存文件。
結果,有設置。
7.再在代碼中打印session_id();,並將要保存的session數據保存后立即打印到日志中,然后到上述session路徑文件夾下執行ls | grep sess_'session_id'查找,有返回,vim打開,其中的值為剛剛保存的,這說明session是ok的,權限也正常,問題應該出現在獲取的時候。
8.為了證明懷疑正確,不使用新框架,另起demo測試,結果證明是對的。
解決:
突然想起小程序是沒有幫忙保存session,查看日志比較后發現果然session_id是不一致的,也就是說每次請求都被服務器認為是一個新的請求,當然就找不到之前的數據了。
我們可以將之前請求的session_id返回到小程序中,並在小程序緩存下來並放到header中,然后再每次請求接口時都帶上去就可以了
var request = (api,params) => new Promise((resolve, reject) => { console.log(params) var headers; /*提交時自動上傳header信息*/ headers = { 'content-type': 'application/x-www-form-urlencoded', 'cookie':wx.getStorageSync("session_id")//讀取cookie }; wx.request({ url: baseUrl + api, data: params, header: headers,//傳在請求的header里 success: (res) => { console.log("api res "); console.log(res); resolve(res.data); }, fail: err => { console.log("api err "); console.log(err); reject(err); } }) })
服務端重新賦予session_id即可。
最后附上session的運行機制:
Session機制是一種服務器端的機制,他將數據保存在服務器端。
當程序需要為某個客戶端的請求創建一個Session的時候,服務器首先檢查這個客戶端的請求里是否已包含一個Session標識,稱為sessionid,如果已包含一個sessionid則說明以前以為此用戶創建過session,服務器就按照sessionid把這個session檢索出來使用即可;否則不包含sessionid,為此客戶端創建一個session並且生成一個與此session相關聯的的sessionid,sessionid的值應該是一個既不會重復,又不容易被找到規律以仿照的字符串,這個sessionid將被在本次響應中返回給客戶端以cookie形式保存。