Laravel 9 + Next.js 购物车Session值始终为Null问题求助
Laravel 9 + Next.js 购物车Session获取为Null问题排查
我正在用Laravel 9和Next.js开发电商应用,添加商品到Laravel Session后,获取购物车数据始终返回Null,以下是相关代码和配置:
Next.js 前端代码
const addToCart = async (productId: number) => { console.log(productId) try { // 添加商品到购物车 const rawResponse = await axios.post(`http://localhost:3001/product/add-to-cart/${productId}`); // 从Session获取购物车数据 const cartData = await axios.get(`http://localhost:3001/products/cart`); } catch (e) { } }
Laravel 后端配置
路由(web.php)
Route::post('product/add-to-cart/{id}', [ProductController::class, 'addProductToCart']); Route::get('products/cart', [ProductController::class, 'getProductsInCart']);
ProductController 代码
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Models\Product; class ProductController extends Controller { public function addProductToCart(Request $request, $id) { $product = Product::findOrFail($id); $cart = session()->get('cart', []); if(isset($cart[$id])) { $cart[$id]['quantity']++; } else { $cart[$id] = [ "productId"=> $product->id, "name" => $product->name, "quantity" => 1, "price" => $product->price, ]; } session()->put('cart', $cart); return response()->json(['success' => 'success'], 200); } public function getProductsInCart(Request $request) { $cart = session()->get('cart'); var_dump($cart); // 此处输出为Null return $cart; } }
Kernel.php CORS及中间件配置
<?php namespace App\Http; use Illuminate\Foundation\Http\Kernel as HttpKernel; class Kernel extends HttpKernel { /** * 应用全局HTTP中间件栈 * * 这些中间件会在每个请求时运行 * * @var array<int, class-string|string> */ protected $middleware = [ \Fruitcake\Cors\HandleCors::class, \Illuminate\Session\Middleware\StartSession::class, \App\Http\Middleware\TrustProxies::class, \Illuminate\Http\Middleware\HandleCors::class, \App\Http\Middleware\PreventRequestsDuringMaintenance::class, \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class, \App\Http\Middleware\TrimStrings::class, \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class, ]; /** * 应用路由中间件组 * * @var array<string, array<int, class-string|string>> */ protected $middlewareGroups = [ 'web' => [ \App\Http\Middleware\EncryptCookies::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, // \App\Http\Middleware\VerifyCsrfToken::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, ], 'api' => [ \App\Http\Middleware\EncryptCookies::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class, // \App\Http\Middleware\VerifyCsrfToken::class, \Illuminate\Routing\Middleware\SubstituteBindings::class, ], ]; /** * 应用路由中间件 * * 这些中间件可分配到组或单独使用 * * @var array<string, class-string|string> */ protected $routeMiddleware = [ 'auth' => \App\Http\Middleware\Authenticate::class, 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, 'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class, 'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class, 'can' => \Illuminate\Auth\Middleware\Authorize::class, 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, 'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class, 'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class, 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, 'isAdmin' => \App\Http\Middleware\isAdmin::class, ]; }
问题现象
调用添加商品接口后,再调用购物车获取接口时,session()->get('cart')返回Null。
排查方向及解决方法
1. 跨域请求未携带Cookie
Next.js的axios请求默认不会携带Cookie,导致两次请求不属于同一个Session。修改前端请求配置,添加withCredentials: true:
const addToCart = async (productId: number) => { console.log(productId) try { // 添加商品时携带Cookie const rawResponse = await axios.post(`http://localhost:3001/product/add-to-cart/${productId}`, {}, { withCredentials: true }); // 获取购物车时携带Cookie const cartData = await axios.get(`http://localhost:3001/products/cart`, { withCredentials: true }); } catch (e) { } }
同时在Laravel的config/cors.php中开启凭证支持:
'supports_credentials' => true,
2. 中间件顺序及重复配置问题
全局中间件中重复添加了HandleCors,且StartSession的位置可能影响Session初始化。建议保留一个Fruitcake的HandleCors,并调整全局中间件顺序:
protected $middleware = [ \App\Http\Middleware\TrustProxies::class, \Fruitcake\Cors\HandleCors::class, \App\Http\Middleware\PreventRequestsDuringMaintenance::class, \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class, \App\Http\Middleware\TrimStrings::class, \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class, ];
Session中间件已在web和api组中配置,无需放到全局中间件。
3. Cookie SameSite设置问题
如果前后端域名不同,Cookie的SameSite策略会影响携带。在config/session.php中调整:
'same_site' => 'lax', // 若使用https,可设置为'none',同时开启secure // 'same_site' => 'none', // 'secure' => true,
内容的提问来源于stack exchange,提问作者Loki
相关产品推荐
相关产品推荐

