在Yii2框架中,当用户会话过期后,传统的页面请求会被自动重定向到登录页面,但对于Ajax请求,这种重定向不会自动生效,因为Ajax请求期望的是JSON/XML等数据响应,而不是HTML页面。
当会话过期时,Yii2的认证系统会拦截请求并尝试重定向,但对于Ajax请求:
在Yii2中,可以通过配置yii\web\User
组件来处理Ajax请求的会话过期问题:
// 在配置文件中
'components' => [
'user' => [
'class' => 'yii\web\User',
'identityClass' => 'app\models\User',
'enableAutoLogin' => true,
'authTimeout' => 3600, // 会话过期时间
'on beforeLogin' => function ($event) {
// 登录前处理
},
'on afterLogin' => function ($event) {
// 登录后处理
},
'loginUrl' => ['site/login'],
'identityCookie' => ['name' => '_identity', 'httpOnly' => true],
'idParam' => '__id',
'enableSession' => true,
],
],
创建一个基础控制器或在现有控制器中添加Ajax响应处理:
public function beforeAction($action)
{
if (Yii::$app->user->isGuest && Yii::$app->request->isAjax) {
Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
Yii::$app->response->data = [
'status' => 'error',
'message' => 'Session expired',
'code' => 401,
'redirect' => Url::to(['site/login'])
];
Yii::$app->response->send();
return false;
}
return parent::beforeAction($action);
}
在前端JavaScript中统一处理Ajax响应:
$(document).ajaxComplete(function(event, xhr, settings) {
try {
var response = JSON.parse(xhr.responseText);
if (response.code === 401 && response.redirect) {
window.location.href = response.redirect;
}
} catch (e) {
// 不是JSON响应,忽略
}
});
或者使用Yii2内置的Pjax处理:
\yii\widgets\Pjax::begin(['timeout' => 5000]);
// 你的内容
\yii\widgets\Pjax::end();
后端控制器代码:
namespace app\controllers;
use Yii;
use yii\web\Controller;
use yii\filters\AccessControl;
class BaseController extends Controller
{
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
[
'allow' => true,
'roles' => ['@'],
],
],
'denyCallback' => function ($rule, $action) {
if (Yii::$app->request->isAjax) {
Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
Yii::$app->response->data = [
'status' => 'error',
'message' => 'Session expired',
'code' => 401,
'redirect' => Yii::$app->user->loginUrl
];
Yii::$app->response->send();
return false;
} else {
return Yii::$app->user->loginRequired();
}
}
],
];
}
}
前端JavaScript代码:
$.ajaxSetup({
dataType: 'json',
contentType: 'application/json',
error: function(xhr) {
try {
var response = JSON.parse(xhr.responseText);
if (response.code === 401 && response.redirect) {
window.location.href = response.redirect;
}
} catch (e) {
// 处理其他错误
}
}
});
这种解决方案适用于:
通过这种方式,可以确保当用户会话过期时,无论是普通请求还是Ajax请求,都能被正确处理并重定向到登录页面。
没有搜到相关的沙龙