CodeIgniter POST请求会话问题:模型设置的会话数据无法读取
嘿,我来帮你搞定这个会话数据不生效的问题!结合你用的CodeIgniter 3.1.7和PHP7.0环境,大概率是这几个环节出了问题,咱们一个个排查:
1. Fetch请求未携带Cookie(最常见原因)
默认情况下,JavaScript的fetch请求不会自动携带当前域名的Cookie,而CodeIgniter的会话完全依赖Cookie来识别用户会话。这就导致你的API请求创建了一个全新的会话,模型里设置的会话数据只存在于这个临时会话中,而页面控制器的请求用的是另一个会话,自然读不到数据。
解决方案:
发送fetch请求时添加credentials配置:
fetch('/你的API路径', { method: 'POST', credentials: 'same-origin', // 同域请求用这个 // 如果是跨域请求,改成 credentials: 'include',同时后端要配置CORS允许带Cookie headers: { 'Content-Type': 'application/x-www-form-urlencoded' // 或者application/json,根据你的API接收方式调整 }, body: new URLSearchParams({ username: '你的用户名', password: '你的密码' }) })
你可以打开浏览器开发者工具的Network面板,查看API请求的请求头里是否有Cookie字段,确认Cookie是否被携带。
2. CodeIgniter会话库初始化问题
确保你的模型和控制器都正确加载了会话库,且会话配置无误:
- 优先在
application/config/autoload.php里自动加载会话库:
$autoload['libraries'] = array('session');
- 如果手动加载,不要在模型和控制器里重复加载,避免创建多个会话实例。
同时检查application/config/config.php里的会话核心配置:
$config['sess_driver'] = 'files'; // 常用的文件驱动,也可以用数据库等其他驱动 $config['sess_save_path'] = APPPATH . 'session/'; // 确保这个目录存在且PHP进程有读写权限 $config['sess_cookie_name'] = 'ci_session'; $config['sess_expiration'] = 7200; $config['sess_match_ip'] = FALSE; // 新手建议先设为FALSE,避免IP变化导致会话失效 $config['sess_time_to_update'] = 300; $config['sess_regenerate_destroy'] = FALSE;
3. 会话存储目录权限不足
如果用的是files会话驱动,application/session目录必须让PHP进程拥有读写权限。可以通过以下命令设置权限(Linux服务器):
chmod 700 application/session chown www-data:www-data application/session # www-data是PHP进程的用户,根据你的服务器调整
如果权限不足,会话数据无法写入磁盘,后续请求自然读不到。
4. 跨域请求的CORS配置问题
如果你的页面和API接口属于不同域名(比如页面在http://localhost:8080,API在http://localhost),除了fetch的credentials: 'include',还需要在API控制器里添加CORS响应头:
public function __construct() { parent::__construct(); // 允许的页面域名,不要用*,否则带Cookie的请求会被浏览器拒绝 header("Access-Control-Allow-Origin: http://你的页面域名"); header("Access-Control-Allow-Credentials: true"); header("Access-Control-Allow-Methods: POST, GET, OPTIONS"); header("Access-Control-Allow-Headers: Content-Type"); // 处理OPTIONS预检请求 if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { exit(); } }
5. API请求提前退出导致会话未保存
如果你的API控制器用了exit()、die()或者直接echo输出后终止请求,CodeIgniter的会话库可能来不及将数据写入存储。必须用CI官方的输出方法返回响应:
public function auth() { $username = $this->input->post('username'); $password = $this->input->post('password'); // 调用模型认证用户 $user = $this->user_model->authenticate($username, $password); if ($user) { // 设置会话数据 $this->session->set_userdata('username', $user['username']); $response = ['status' => 'success', 'message' => '登录成功']; } else { $response = ['status' => 'error', 'message' => '用户名或密码错误']; } // 用CI输出方法返回JSON $this->output ->set_content_type('application/json') ->set_output(json_encode($response)); }
最后验证步骤
- 登录后,查看
application/session目录下是否生成了新的会话文件; - 页面控制器里用
var_dump($this->session->all_userdata());打印所有会话数据,确认是否存在username字段; - 用浏览器开发者工具的Application面板查看Cookie里的
ci_session值,确认请求之间Cookie是否一致。
内容的提问来源于stack exchange,提问作者SpeedOfRound

