Не могу найти указанный ключ формы (action)

09.05.2020
5388 просмотров

В процессе апгрейда некоторых MODX сайтов на поддержку Google Recaptcha 3 в отправке форм обратной связи столкнулся с ошибкой «Не могу найти указанный ключ формы (action)». Причина такого сообщения чаще всего кроется в наличии ненужного кеша. Но Ajax Form запускался некешированным, ошибок в формах отправки не было, а проблема — была :) Ошибка «Не могу найти указанный ключ формы (action)» связана с механизмом защиты CSRF в MODX, который использует уникальный токен для каждой формы. Этот токен генерируется при загрузке страницы и должен быть актуальным на момент отправки формы, поэтому в общих чертах так или иначе корень проблемы в кэше, когда вместо актуального, выдаётся устаревший CSRF-токен.

Достаточно быстро выяснилась причина: сайт кешировался средствами nginx через директиву «fastcgi_cache». Проблема не проявлялась, если сессия была авторизована в админке, потому что тогда включалось правило «fastcgi_no_cache/fastcgi_cache_bypass $http_authorization». Для решения проблемы потребовалось, учитывая объявленную в секции «server» переменную «set $no_cache 0» для общего включения кэша, прибавить к исключениям правило, отключающее кэширование для AJAX-запросов :


set $no_cache 0;

location ~ \.php$ {

 # Отключаем кэширование для админки MODX и API
 if ($request_uri ~* "^/(manager|api)/") {
    set $no_cache 1;
 }

 # Отключаем кэширование AJAX
 if ($http_x_requested_with != "XMLHttpRequest") {
    set $no_cache 1;
 }
}

fastcgi_cache_bypass $no_cache;

Правило nginx ловит ajax запросы и при их обработке не обращается к кэшу сайта. Если кто-то вместо nginx до сих пор пользуется каменным топором Apache, то копайте в сторону перехвата кэша Ajax в апаче самостоятельно.

Если нет возможности сделать запись в корневой секции php, то надо присвоить cookie через OnLoadWebDocument плагин


$content = $modx->resource->getContent();
if (strpos($content, "//тут описываем, что ищем, исходя из содержимого ресурса, например !AjaxForm //") !== false) {
    setcookie('form_page', '1', 0, '/');
} else {
    setcookie('form_page', '0', 0, '/');
}

И «ловить» её таким вот образом:

fastcgi_cache_bypass $cookie_form_page;

Дополнительно не лишним будет отключить кэширование в настройках ресурса (страницы) MODX на которой выводится форма отправки.

Оставьте комментарий