Laravel 的 Cookie 用起來蠻優雅的,但還是踩了不少坑,主要是不熟悉框架所致 ?。其實本質還是在使用全域性變數 $_COOKIE
,由於原生的使用方式不夠友好,因此既然選擇了框架,就充分利用其提供的友好封裝層。
先來一個最簡單的示例:
public function setCookie()
{
return response('Hello Cookie')->cookie('test', '123', 60);
}
public function getCookie()
{
echo request()->cookie('test');
}
首先我們要明確 Cookie 是儲存在瀏覽器端的(也就是使用者端),所以它就必須依附於具體某個請求和響應。而 Session 是儲存在服務端的,它不需要依附在某個請求或者響應頭中。
所以我們在使用 Cookie 的時候,就必須配合 Request 和 Response。
獲取 Cookie
Laravel 給我們提供了靈活的獲取 Cookie 的方式,具體喜歡哪一種按個人喜好來吧~
- 透過呼叫
Illuminate\Http\Request
例項物件的cookie
方法獲取$value = $request->cookie('key'); $value = request()->cookie('key');
- 透過 Cookie Facade 方式
use Illuminate\Support\Facades\Cookie; // ... $value = Cookie::get('key');
其實第二種方式獲取 Cookie 值也是透過第一種方式呼叫的,我們可以在 Illuminate\Support\Facades\Cookie
類中的 get()
方法中看到:
public static function get($key = null, $default = null)
{
return static::$app['request']->cookie($key, $default);
}
設定 Cookie
我們在需要設定 Cookie 的請求方法中,透過 Response 的 cookie()
方法進行設定:
$value = response('Hello Cookie')->cookie('key', 'value', 60);
$value = response('Hello Cookie')->withCookie('key', 'value', 60);
上面兩種方式均可,第一種方式其實就是呼叫了第二種方式(有時候選擇多了反而增加記憶成本 ?)。
還有一種使用 helper 函式。。。
function cookie($name = null, $value = null, $minutes = 0, $path = null, $domain = null, $secure = false, $httpOnly = true, $raw = false, $sameSite = null) {}
推薦還是使用第一種方式,因為可以正確的理解 Cookie 的設定方式。
刪除 Cookie
開篇也說過 Cookie 是儲存在客戶端的,所以刪除的操作其實服務端是沒許可權去做的,那麼這裡所謂刪除其實就是使 Cookie 失效。Laravel 提供了友好的 API 供我們呼叫,感謝 Laravel ?~
use Illuminate\Support\Facades\Cookie;
// ...
Cookie::forget('key');
細心你會發現這個類中沒有這個靜態方法,和 Cookie::forever('key', 'value')
一樣,這些好用的 API 是 Illuminate\Cookie\CookieJar
這個類提供的(這個類是透過 ServiceProvider 在 Illuminate\Foundation\Application
類中註冊,然後在 /bootstrap/app.php
例項化,詳細的讀原始碼~)
public function forget($name, $path = null, $domain = null)
{
return $this->make($name, null, -2628000, $path, $domain);
}
我們可以看到其實就是將 Cookie 的有效期(Expires/Max-Age)設定成過去時即可。
更細心的你會發現光是這一句並沒有什麼卵用啊 ?,別忘了我們要把更改後的 Cookie 加入到響應頭中,這樣客戶端才會修改 Cookie 值(說到這裡其實本質還是在設定 Cookie 而已 ?)。
use Illuminate\Support\Facades\Cookie;
// ...
public function demo()
{
$cookie = Cookie::forget('key');
return response('xxx')->cookie($cookie);
}
明文 Cookie
很多時候 Cookie 是需要被前端童鞋使用的,但是預設情況下 Laravel 在響應頭中新增的 Cookie 資訊是加密過的,類似 eyJpdiI6IjRwOFMyTkl2aGs2TGt4OUcxYXRNXC9BPT0iLCJ2YWx1ZSI6IkpHN0Fqb0ZSaDFxVHE0OHdFRXdXMHc9PSIsIm1hYyI6Ijc2MTljZDVmZDI1Mjg5MTk3NTBlZGM0MzUxMjUyZjQ5MzcxOGE1MWU4Y2ViZTBlYTY5YWRjZjNkZjUwNzNkMDEifQ%3D%3D
,這種時候就得將那些需要 明文 傳輸的 Cookie 加入到 白名單 中去:
在 /app/Http/Middleware/EncryptCookies.php
中的 $except
陣列中將其加入,
protected $except = [
'key'
];
小結
其實 Laravel 的 Cookie 還有不少好用的方法,比如 Cookie::has('key')
判斷在請求頭中是否存在某個 Cookie。多去看看框架原始碼,驚喜彩蛋 ? 總是讓你那麼開心 ?!
本作品採用《CC 協議》,轉載必須註明作者和本文連結