Laravel 5.1 Cookie队列异常:存入后getQueuedCookies返回空数组
我来帮你理清楚这个问题哈,Laravel里的Cookie::queue()机制其实有几个容易踩的细节坑:
首先得明确:Cookie::queue()是把Cookie加到响应的发送队列里,它不会立刻出现在当前请求的Cookie集合中。因为HTTP是无状态的,队列里的Cookie要等服务器把响应发给浏览器,浏览器保存后,下一次请求才会把这个Cookie带回来。所以你当前请求里用Cookie::has()或者Cookie::get()肯定拿不到,这俩方法读的是浏览器这次请求发过来的Cookie,不是你刚加到队列里的那个。
接下来说说Cookie::getQueuedCookies()返回空数组的可能原因:
1. 调用时机不对,队列已经被处理了
Laravel会在响应发送给浏览器之前,自动把队列里的Cookie塞进响应头的Set-Cookie字段里,然后清空队列。如果你是在已经返回响应之后调用dd(Cookie::getQueuedCookies()),那队列早就被处理完清空了,自然返回空数组。
举个例子:你在控制器里先写了return view('xxx'),之后再去打印队列Cookie,这时候响应已经开始发送,队列肯定是空的。解决办法就是把打印的代码放在返回响应之前执行。
2. 不在HTTP请求上下文里调用
如果你的代码是在命令行脚本、队列任务这类非HTTP请求的环境里调用Cookie::queue(),因为没有对应的HTTP响应对象,这些Cookie没法被绑定到响应上,队列也不会正常保存,调用getQueuedCookies()自然也拿不到内容。要确保你的代码是在路由、控制器、HTTP中间件这些HTTP请求生命周期内执行的。
怎么验证队列是否真的生效?
如果你想确认队列里的Cookie会不会被发送给浏览器,别用getQueuedCookies()了,换个方式:
Cookie::queue('session', $response['session'], 3); // 查看即将随响应发送的所有Cookie dd(response()->headers->getCookies());
或者直接用浏览器的开发者工具,在Network面板里看响应头的Set-Cookie字段,有没有你设置的那个Cookie。
最后再总结下
- 当前请求里别想用
Cookie::get()/Cookie::has()拿到刚进队列的Cookie,这是机制问题,不是你代码写错了。 getQueuedCookies()返回空,大概率是你调用晚了,队列已经被处理清空了。- 验证队列是否生效,看响应头的
Set-Cookie才是正确姿势。
内容的提问来源于stack exchange,提问作者code-8

