Yii2正式服务器PHP延迟2分钟才可读取JS写入的Cookie问题
问题现象
- 本地开发环境、测试服务器Cookie读写逻辑运行完全正常,部署到正式服务器后出现两类异常:
- JS写入Cookie完成后跳转首页,PHP在2分钟内无法读取到指定的
tokenCookie值,等待2分钟后读取自动恢复正常 - 手动修改Cookie值后,PHP读取到的始终是已失效的旧Cookie值,无法获取最新写入的内容
- JS写入Cookie完成后跳转首页,PHP在2分钟内无法读取到指定的
复现流程
- 发起AJAX请求,在请求成功回调中通过JS写入
token到Cookie,写入完成后跳转站点首页,对应JS代码如下:
success: function (data) { document.cookie = "token="+data.data.token+";path=/"; window.location.href="/"; }
- 在首页控制器的index动作中编写代码,直接读取
tokenCookie并输出,对应PHP代码如下:
echo $_COOKIE["token"]; die();
- 跳转至首页后,前2分钟访问页面无任何输出,2分钟后才可正常输出Cookie值;修改Cookie值后,访问页面始终输出已被替换的旧Cookie值。
根因分析
该问题和Yii2框架本身无关,核心触发原因是正式服务器前置的代理层(CDN、WAF、Nginx反向代理)默认开启了动态请求缓存,且默认缓存TTL为120秒(即你遇到的2分钟延迟):
- 缓存有效期内,代理层不会把客户端最新的请求头转发给后端PHP,直接返回节点上缓存的旧响应内容,此时后端拿不到新写入的Cookie,修改Cookie后也会命中旧缓存返回旧值
- 缓存过期后,代理层才会向后端源站转发最新请求,此时PHP才能正常读取到最新的Cookie值
少数场景下也会因为JS写入Cookie后立即跳转,浏览器未完成Cookie写入就发起首页请求,导致首次请求不带Cookie,但该问题不会出现固定2分钟延迟、旧值回显的特征。
修复方案
按优先级逐一排查验证:
- 调整前置代理缓存规则
- 临时关闭CDN、WAF的页面缓存功能,直接访问源站验证Cookie读写是否恢复正常
- 针对需要读取动态Cookie的路径(如首页、接口路径),配置Nginx跳过缓存规则:
location / { proxy_no_cache $cookie_token; proxy_cache_bypass $cookie_token; # 保留原有反向代理配置 }- 禁止对
.php动态请求设置强制缓存,动态请求缓存规则需根据业务场景按需配置,不要直接使用默认120秒TTL
- 优化JS Cookie写入逻辑
补全Cookie属性,增加跳转延迟避免浏览器写入未完成就发起新请求:success: function (data) { // 补全有效期、作用域、SameSite属性,和服务端配置保持一致 document.cookie = `token=${data.data.token};path=/;max-age=86400;SameSite=Lax`; // 延迟50ms跳转,确保Cookie写入完成 setTimeout(() => { window.location.href="/"; }, 50); } - 修正框架层Cookie读取逻辑
不要直接读取原生$_COOKIE全局变量,优先使用Yii2框架封装的Cookie组件读取,避免框架内置的Cookie校验、过滤逻辑导致值异常:
同时检查项目内是否有全局前置行为类在请求初始化阶段提前缓存了$token = Yii::$app->request->cookies->getValue('token', ''); echo $token; die();$_COOKIE值,导致后续读取拿到的是请求初始化时的旧值。
内容的提问来源于stack exchange,提问作者Tohear
相关产品推荐
相关产品推荐

