Периодически возникала потребность, чтобы в композитном режиме можно было учитывать дополнительные переменные, которых нет в URL.
Основные случаи, которые требовалось учитывать при построении ключа композитного кеша, и следовательно отдавать разный html:- HTTP_USER_AGENT - для отличия мобильных и десктопных браузеров
- HTTP_ACCEPT - проверять поддержку WEBP
- COOKIE - в зависимости от кук
Я реализовал небольшой хак через rewrite в Nginx. Мой метод основан на добавлении в $_SERVER["REQUEST_URI"] дополнительных переменных через Nginx. Далее привожу 2 примера.
Первый пример для HTTP_USER_AGENT:
В секции для нужного хоста в Nginx добавляю:
if ($http_user_agent ~* "mobile") { rewrite ^/composite_test/$ /composite_test/?MOBILE=Y break; } |
В случае с мобильным браузером в Apache уходит url с дополнительным параметром MOBILE=Y и в $_SERVER["REQUEST_URI"] будет /composite_test/?MOBILE=Y, при этом url в браузере останется /composite_test/.
Важно делать это через Nginx, а не Apache. Битрикс использует $_SERVER["REQUEST_URI"] для построения ключа композитного кеша и не использует $_SERVER["QUERY_STRING"].
Если использовать mod_rewrite в Apache, то MOBILE=Y попадёт в $_SERVER["QUERY_STRING"], а $_SERVER["REQUEST_URI"] останется таким же.
Второй пример для COOKIE:
Nginx поддерживает cookie и можно написать условие вида:
if ($cookie_VARNAME = 1) { rewrite ^/composite_test/$ /composite_test/?VARNAME=1 break; } |
С cookie правда есть нюанс, что их ещё нужно установить, для этого возможно потребуется сделать страницу, без композитного кеша, которая будет эти куки ставить. Это зависит от требуемой логики.
В целом можно использовать любые переменные доступные в Nginx и таким образом формировать разные url для Apache.
Я привел базовые примеры, которые можно адаптировать под нужды конкретного проекта. Правда замечу, что необходимо иметь доступ к настройкам Nginx на сервере.
Данная методика подходит для простейших условий. Если требуется полноценная логика и расчёты, то нужно использовать композит с динамическими областями, как это и задумано логикой продукта.