Skip to content

Laravel - Cookie

HTTP cookie 是服务器发送到用户 Web 浏览器的小块数据。浏览器可能会存储它,并在后续请求发送回同一服务器时将其发送回来。Laravel 提供了创建、检索和管理 cookie 的简便方法。默认情况下,Laravel 生成的所有 cookie 都是加密并签名的,因此客户端无法修改或读取它们。

在 Laravel 中有几种设置 cookie 的方法:

你可以使用 cookie 方法将 cookie 附加到外发的 Illuminate\Http\Response 实例。此方法接受名称、值、持续时间(分钟)、路径、域名、安全标志(secure)和 httpOnly 参数。

use Illuminate\Http\Response;
// 在控制器方法中
return response('Hello World')->cookie(
'user_preference', 'dark_mode', 60 // 60 分钟
);
// 带更多选项:
return response('Another Response')->cookie(
'session_id', 'xyz123', 120, '/', null, true, true
// 名称, 值, 分钟, 路径, 域名, 安全标志, httpOnly
);
Section titled “2. 使用 Cookie Facade(将 Cookie 加入队列):”

如果你想在创建响应之前设置 cookie,可以使用 Cookie Facade 的 queue 方法。这些 cookie 将自动附加到外发响应中。

use Illuminate\Support\Facades\Cookie;
// 在控制器方法或服务中
Cookie::queue('username', 'john_doe', 60 * 24); // cookie 有效期 1 天
// 你也可以将一个 Cookie 实例加入队列以获得更多控制:
$cookie = cookie('theme', 'light', 120, null, null, false, true); // httpOnly = true
Cookie::queue($cookie);

要创建一个长期有效的 cookie(实际上是“永久”,通常是 5 年),可以使用 forever 方法:

Cookie::queue(Cookie::forever('api_key', 'secret-api-value'));
// 或者附加到响应时:
return response('API Key Set')->cookie(Cookie::forever('api_key', 'secret-api-value'));

设置 cookie 后,你可以使用 Illuminate\Http\Request 实例的 cookie 方法或 Cookie Facade 的 get 方法从传入的请求中检索其值。

// 在控制器方法中
use Illuminate\Http\Request;
public function showUserSettings(Request $request)
{
$userPreference = $request->cookie('user_preference'); // 返回 'dark_mode' 或 null
$username = $request->cookie('username', 'default_guest'); // 带默认值
// return view('settings', ['preference' => $userPreference, 'username' => $username]);
return "Preference: {$userPreference}, Username: {$username}";
}
use Illuminate\Support\Facades\Cookie;
$theme = Cookie::get('theme'); // 返回 'light' 或 null
$apiKey = Cookie::get('api_key', null); // 可以指定默认值

要删除 cookie,你可以将一个同名但值为空且时间戳已过期的 cookie 加入队列。Laravel 提供了一个 forget 方法来实现这一点。

1. 使用 Cookie::queue() 配合 Cookie::forget():

Section titled “1. 使用 Cookie::queue() 配合 Cookie::forget():”
Cookie::queue(Cookie::forget('user_preference'));
Section titled “2. 将一个已过期的 Cookie 附加到响应:”
return response('Cookie removed')->withoutCookie('username');

withoutCookie 方法实际上实现了与将 forgotten cookie 加入队列相同的效果。

Section titled “示例:在控制器中实现 Cookie 操作”

步骤 1: 创建一个 CookieDemoController。

php artisan make:controller CookieDemoController

步骤 2: 在 app/Http/Controllers/CookieDemoController.php 中添加方法。

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use Illuminate\Support\Facades\Cookie;
class CookieDemoController extends Controller
{
public function setAppCookie(Request $request): Response
{
$minutes = 60; // cookie 有效期 60 分钟
$cookieValue = 'LaravelTutorial-' . time();
// 使用 Cookie::queue (cookie 将自动添加到响应中)
// Cookie::queue('my_app_cookie', $cookieValue, $minutes);
// return response('Cookie has been set via queue!');
// 或者直接附加到响应
return response('Cookie has been set directly!')
->cookie('my_app_cookie', $cookieValue, $minutes);
}
public function getAppCookie(Request $request): string
{
$value = $request->cookie('my_app_cookie');
// 或者: $value = Cookie::get('my_app_cookie');
if ($value) {
return 'Retrieved cookie value: ' . $value;
}
return 'Cookie not found or expired.';
}
public function deleteAppCookie(Request $request): Response
{
// 使用 Cookie::queue 配合 Cookie::forget()
// Cookie::queue(Cookie::forget('my_app_cookie'));
// return response('Cookie queued for deletion!');
// 或者直接从响应中移除
return response('Cookie has been deleted!')
->withoutCookie('my_app_cookie');
}
}

步骤 3: 在 routes/web.php 中定义路由。

use App\Http\Controllers\CookieDemoController;
Route::get('/cookie/set', [CookieDemoController::class, 'setAppCookie'])->name('cookie.set');
Route::get('/cookie/get', [CookieDemoController::class, 'getAppCookie'])->name('cookie.get');
Route::get('/cookie/delete', [CookieDemoController::class, 'deleteAppCookie'])->name('cookie.delete');

步骤 4: 通过访问以下 URL 测试 cookie 操作:

  • http://your-app.test/cookie/set:设置 cookie。检查浏览器的开发者工具(Application > Cookies)查看它。
  • http://your-app.test/cookie/get:检索并显示 cookie 的值。
  • http://your-app.test/cookie/delete:删除 cookie。刷新获取 URL 或检查开发者工具确认它已删除。

实际应用:记住用户偏好设置

Cookie 通常用于存储非敏感的用户偏好设置,例如:

  • 主题(深色/浅色模式)
  • 语言选择
  • 访客用户的购物车商品
  • 记住用户是否已看过欢迎消息或促销弹出窗口。

常见的学习障碍:Cookie 未立即设置

一个常见的困惑点是 cookie 是随 HTTP 响应发送到浏览器的。这意味着如果你在同一个请求周期内设置了一个 cookie 然后尝试使用 $request->cookie() 检索它,你将无法获得新设置的值。浏览器需要接收响应,存储 cookie,然后在后续请求中将其发送回来。Cookie::queue() 有助于管理这种情况,因为 Laravel 会确保将队列中的 cookie 添加到外发响应中。