Не могу найти указанный ключ формы (action)
В процессе апгрейда некоторых 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 на которой выводится форма отправки.