From 2e3c52bec0dbc078801281809ebad82c7b7e681d Mon Sep 17 00:00:00 2001 From: Aleksey Filippov Date: Wed, 4 Mar 2026 20:31:25 +0300 Subject: [PATCH] fix(TO8-48): increase session timeout to 4h, add JS keep-alive ping Prevent BadRequestHttpException (Unable to verify your data submission) in WriteOffsErpController caused by PHP session expiry during long form filling. - erp24/config/web.php: add session component, timeout=14400 (4 hours) - SiteController: add actionKeepAlive() endpoint for JS ping - session-keep-alive.js: ping /site/keep-alive every 15 min, pause on hidden tab, skip during upload - main.php: register session-keep-alive.js globally --- erp24/config/web.php | 4 +++ erp24/controllers/SiteController.php | 10 +++++++ erp24/views/layouts/main.php | 2 ++ erp24/web/js/session-keep-alive.js | 43 ++++++++++++++++++++++++++++ 4 files changed, 59 insertions(+) create mode 100644 erp24/web/js/session-keep-alive.js diff --git a/erp24/config/web.php b/erp24/config/web.php index 72610055..303d94c2 100644 --- a/erp24/config/web.php +++ b/erp24/config/web.php @@ -63,6 +63,10 @@ $config = [ // 'loginUrl' => ['/site/login'], 'enableAutoLogin' => true, ], + 'session' => [ + 'class' => 'yii\web\Session', + 'timeout' => 14400, // 4 часа — формы списаний требуют длительного заполнения + ], 'errorHandler' => [ 'errorAction' => 'site/error', ], diff --git a/erp24/controllers/SiteController.php b/erp24/controllers/SiteController.php index 872d568e..d4dbffcf 100644 --- a/erp24/controllers/SiteController.php +++ b/erp24/controllers/SiteController.php @@ -123,6 +123,16 @@ class SiteController extends Controller return $this->render('about'); } + /** + * Продлевает PHP-сессию (keep-alive пинг от JS). + * Предотвращает истечение CSRF-токена при длительном заполнении форм. + */ + public function actionKeepAlive() + { + Yii::$app->response->format = Response::FORMAT_JSON; + return ['ok' => true]; + } + public function actionMenuTree() { // $client = new Client(['base_uri' => Yii::$app->params['API2_URL']]); diff --git a/erp24/views/layouts/main.php b/erp24/views/layouts/main.php index 8da450fa..a16530b0 100755 --- a/erp24/views/layouts/main.php +++ b/erp24/views/layouts/main.php @@ -13,6 +13,8 @@ use yii\widgets\Breadcrumbs; // Register Shift Reminder JavaScript $this->registerJsFile('/js/shift-reminder.js', ['position' => \yii\web\View::POS_END]); +// Session keep-alive: предотвращает истечение CSRF-токена при длительном заполнении форм +$this->registerJsFile('/js/session-keep-alive.js', ['position' => \yii\web\View::POS_END]); ?> beginPage() ?> diff --git a/erp24/web/js/session-keep-alive.js b/erp24/web/js/session-keep-alive.js new file mode 100644 index 00000000..b58883f3 --- /dev/null +++ b/erp24/web/js/session-keep-alive.js @@ -0,0 +1,43 @@ +/** + * Session keep-alive: периодический пинг для продления PHP-сессии. + * Предотвращает истечение CSRF-токена при длительном заполнении форм. + */ +(function () { + var INTERVAL_MS = 900000; // 15 минут + var intervalId = null; + + function ping() { + if (window._uploadInProgress) return; + + $.ajax({ + method: 'GET', + url: '/site/keep-alive', + dataType: 'json' + }); + } + + function start() { + if (!intervalId) { + intervalId = setInterval(ping, INTERVAL_MS); + } + } + + function stop() { + if (intervalId) { + clearInterval(intervalId); + intervalId = null; + } + } + + // Пауза при неактивной вкладке + document.addEventListener('visibilitychange', function () { + if (document.hidden) { + stop(); + } else { + ping(); + start(); + } + }); + + start(); +})(); -- 2.39.5