Администратор сайта видит не тот сайт, что посетители. Он залогинен, и его запросы идут мимо кэша: каждая страница рендерится для него заново. Это удобно и опасно одновременно.
Это четвёртая часть цикла «WordPress на кэшируемом сайте»: вошедшие пользователи, записи под паролем, предпросмотр и интерфейс для редактора на кэшируемом сайте.
Три служебные куки в обходе кэша
| Кука | Чья | Почему мимо кэша |
|---|---|---|
wordpress_logged_in_* | вошедший пользователь | ему рисуется админ-панель, черновики, предпросмотр |
wp_postpass_* | тот, кто ввёл пароль записи | ему показывается содержимое, остальным — форма пароля |
comment_author_* | автор комментария | штатный WordPress показывает ему его комментарий на модерации |
У всех трёх ответ зависит от конкретного человека. В кэш такой ответ класть нельзя, и брать оттуда для этого человека тоже нельзя.
Обход и запрет записи — две разные настройки
В nginx «не брать из кэша» и «не класть в кэш» задаются отдельно. Если указать только первое, страницу администратора с его панелью nginx сохранит и отдаст следующему анониму:
fastcgi_cache_bypass $skip_cache; # не отдавать из кэша
fastcgi_no_cache $skip_cache; # и не сохранять в кэш
Обе строки с одной и той же переменной — обязательная пара.
«У меня всё обновилось» — а у посетителей нет
Самая частая ловушка: администратор поправил текст, обновил страницу, увидел правку — и считает, что её видят все. Он-то видит живой рендер, а посетители — кэш. Если сброс для этого типа правки не сработал, разницу заметит только посетитель.
Проверять правку надо глазами анонима: окно инкогнито или запрос из консоли без кук. Заодно видно статус кэша в заголовке ответа.
curl -s -o /dev/null -D - https://сайт/страница/ | grep -i x-cache-status
Предпросмотр и пароль
Предпросмотр черновика (?preview=true) открывает только вошедший, а значит, он уже идёт мимо кэша — отдельных правил не нужно. С паролем на записи в кэш попадает только вариант с формой пароля: кто пароль ввёл, получает куку и дальше идёт мимо кэша.
Интерфейс только для редактора
Хочется кнопку «изменить» прямо на странице, плашку «черновик», ссылку в админку у блока. На сайте, где мы это делали, админ-панель WordPress на страницах выключена, а кука входа помечена httponly — скрипт не может узнать, вошёл ли человек. Как показать интерфейс только редактору, не испортив анонимный HTML:
- сервер добавляет класс на
<body>, только если пользователь вошёл и может редактировать. Вошедшие идут мимо кэша, поэтому анонимный HTML от этого не меняется ни на байт; - данные для кнопок — идентификатор записи, название блока — лежат в общей разметке в
data-*-атрибутах, одинаковых для всех; - кнопки и плашки дорисовывает скрипт по классу, а тяжёлый код подключается динамическим
import()только при этом классе.
add_filter('body_class', function ($classes) {
if (is_user_logged_in() && current_user_can('edit_posts')) {
$classes[] = 'isEditor';
}
return $classes;
});
if (document.body.classList.contains('isEditor')) {
import('./editorTools').then((m) => m.default());
}
Аноним не скачивает ни байта кода редактора, а кэш остаётся общим.
Кэш фрагментов и вошедшие
Если у сайта есть свой кэш ajax-блоков, вопрос «обходить ли его для администратора» решается отдельно. Токены форм в такие блоки класть нельзя в любом случае — почему, в 17-й части цикла про кэш фрагментов.
Редактору нужно больше инструментов прямо на страницах?
Пришлите адрес — сделаю так, чтобы посетители и кэш этого не заметили.
// загружаю комментарии…