Yii2 API接口设置Last-Modified响应头及缓存控制问题
解决Yii2 API中Last-Modified响应头设置问题
我来帮你梳理下这个问题的根源,以及对应的解决办法:
1. 直接传字符串导致Last-Modified变成1970日期的原因
Yii2的Response::setLastModified()方法并不接受纯日期字符串(比如'2020-01-19')作为参数,它只认两种类型:Unix时间戳(整数) 或者 DateTimeInterface实例。当你直接传字符串时,框架会把它解析为无效值,最终默认使用时间戳0,也就是Thu, 01 Jan 1970 00:00:00 GMT。
2. date_format触发500错误的问题
你应该是直接把日期字符串传给了date_format()函数,但这个函数的第一个参数必须是DateTime对象,而不是字符串。正确的用法是先创建DateTime实例,再调用格式化方法——不过其实设置Last-Modified根本不需要手动格式化,直接传对象或时间戳就行。
3. 正确的实现代码
下面是完整的修正代码,同时处理Last-Modified和Cache-Control设置:
public function actionEvents() { // 1. 正确设置Last-Modified的两种方式选其一 // 方式A:使用DateTime对象(推荐,可读性强) $lastModifiedDate = new \DateTime('2020-01-19'); Yii::$app->response->setLastModified($lastModifiedDate); // 方式B:转换为Unix时间戳 // $lastModifiedTimestamp = strtotime('2020-01-19'); // Yii::$app->response->setLastModified($lastModifiedTimestamp); // 2. 设置Cache-Control为1分钟(60秒) Yii::$app->response->headers->set('Cache-Control', 'max-age=60, public'); // 可选:自动处理304 Not Modified响应(优化性能) if (Yii::$app->response->checkIfNotModified($lastModifiedDate->getTimestamp())) { Yii::$app->end(); } // 你的业务逻辑代码... $data = // 从数据库或其他来源获取数据 return $data; }
4. 额外注意事项
- 检查是否有其他代码(比如CORS过滤器、自定义行为、其他控制器逻辑)覆盖了响应头。比如有些RESTful模板会默认设置
Cache-Control: no-store,你需要确保自己的设置在这些代码之后执行,或者直接覆盖它们。 - 如果你的Last-Modified是基于数据的实际更新时间(比如数据库记录的updated_at字段),记得用实际的时间值替换示例中的
'2020-01-19'。
内容的提问来源于stack exchange,提问作者Joshi
相关产品推荐
相关产品推荐

