Перенос сайта с Тильды: 31 файл скачается, а десять служб — нет
Скачать страницу мешает не защита, а устройство. В HTML снятого магазина названы 20 файлов JavaScript, 11 файлов CSS и 7 картинок с домена Тильды — это то, что видно в списке загрузок. Ещё 21 файл JavaScript и 4 файла CSS названы только внутри кода: они приезжают, когда посетитель откроет фильтр, попап товара или подсказку. А формы, расчёт доставки, брошенная корзина и кабинет покупателя обращаются к адресам, которых в HTML нет вообще.
Короткий ответ
Разметка, текст, картинки и стили переносятся — они лежат в файлах. Не переносятся службы: в HTML снятого магазина стоят ссылки на 31 файл кода и 7 картинок с домена Тильды, но ещё 25 файлов её код догружает сам, а отправка формы, доставка, брошенная корзина и кабинет обращаются к адресам, собранным внутри кода. Скачанная копия — витрина без этих служб.
Что именно я мерил
Честно о границах: экспортного архива у меня нет, и я его не мерил. У меня два источника — HTML уже опубликованной страницы магазина на Тильде (140 889 байт) и 53 файла её рантайма. Всё ниже выведено из них.
Для вопроса о переносе это даже точнее, чем архив: состав архива Тильда может менять, а поведение кода в браузере — то, что определяет, заработает копия или нет. Функция, которая собирает адрес файла при каждом вызове, будет собирать его так же, как бы вы файлы ни получили.
Что видно в списке загрузок
В атрибутах страницы 50 ссылок на домен tildacdn. Считать их нужно с оглядкой:
теги Тильды написаны в двойных кавычках, а картинки внутри Zero Block — в
одинарных, и поиск только по двойным теряет часть картинок.
| Атрибут | Ссылок | Что это |
|---|---|---|
src= | 25 | файлы JavaScript и картинки |
href= | 19 | файлы CSS, фавиконка и две подсказки dns-prefetch |
data-original= | 6 | картинки для отложенной загрузки |
Уникальных файлов за этими ссылками:
| Хост | JavaScript | CSS | Картинки |
|---|---|---|---|
static.tildacdn.com | 20 | 11 | 7 |
neo.tildacdn.com | 1 | 0 | 0 |
ws.tildacdn.com | 0 | 0 | 0 |
Что из этого следует для переноса:
- Своих файлов на странице почти нет. Единственная относительная ссылка на файл
—
/custom.css?t=1782465558. Всё остальное — абсолютные адреса на домен Тильды. Относительных ссылок 13, и все они ведут на страницы сайта, не на файлы. - Картинок в CSS нет ни одной. В 22 встроенных блоках стилей на 66 380 байт —
ноль конструкций
url(). Все картинки приходят через тегиimg(их на странице 7) и через атрибутыdata-original(6), то есть их список можно собрать из разметки. - Один файл едет с другого домена.
tilda-fallback-1.0.min.jsподключён в HTML сneo.tildacdn.com, а не сstatic. - Один файл в разметке не найти. Встроенный скрипт через 2000 мс добавляет на
страницу
tilda-stat-1.0.min.js— статистику. Среди тегов её нет, в списке загрузок она появится. - Есть подсказка браузеру на домен, с которого ничего не грузится. В HTML стоит
<link rel="dns-prefetch" href="https://ws.tildacdn.com">, но ни один тег на странице кws.tildacdn.comне обращается.
Двадцать пять файлов, которых в списке загрузок нет
Это главная ловушка переноса. Способ «открыть панель разработчика и скачать всё из списка загрузок» даёт копию, которая ломается не сразу, а когда посетитель нажмёт на что-то конкретное. Потому что часть имён файлов существует только внутри кода:
| Загрузчик | Что догружает | Когда |
|---|---|---|
tilda-catalog-1.1 | tilda-catalog-filters-1.0 | открыт фильтр каталога |
tilda-catalog-1.1 | tilda-catalog-pagination-1.0 | включена постраничная навигация |
tilda-catalog-1.1 | tilda-catalog-tabs-1.0 | у каталога есть табы |
tilda-catalog-1.1 | tilda-catalog-slds-1.0 | у товара непустая галерея в попапе |
tilda-catalog-1.1 | tilda-tooltip-1.0 | вместе с фильтрами |
tilda-catalog-1.1, файл блоков страницы | tilda-hover-zoom-1.0 | не мобильный и есть [data-hover-zoom] |
tilda-cart-1.1, tilda-delivery-1.0 | tilda-cart-discounts-1.0 | в корзине есть скидки |
tilda-cart-1.1, tilda-delivery-1.0 | tilda-cart-fullscreen-1.1 | корзина на весь экран |
tilda-cart-1.1, tilda-delivery-1.0 | tilda-cart-restorefields-1.0 | восстановление полей заказа |
tilda-cart-1.1, tilda-delivery-1.0 | tilda-cart-restoreorder-1.0 | восстановление самого заказа |
tilda-forms-1.0 | tilda-forms-custommask-1.0 | своя маска в поле |
tilda-forms-1.0 | tilda-forms-dict-1.0 | нужны словари форм |
tilda-forms-1.0 | tilda-forms-payments-1.0 | в форме есть оплата |
tilda-zero-1.1 | tilda-undercut-1.0 | подрезка в Zero Block |
tilda-lazyload-1.0 | tilda-errors-1.0 | картинка не загрузилась |
tilda-fallback-1.0 | tilda-fallback-advanced-1.0 | какой-то файл не загрузился |
tilda-buyer-dashboard-1.0 | tilda-members-scripts и ещё 8 файлов | открыт кабинет покупателя |
Итого 21 файл JavaScript и 4 файла CSS.
Отдельно стоит посмотреть на фильтр каталога, потому что он показывает механику
целиком: tilda-catalog-filters-1.0.min.css есть в разметке страницы, а
tilda-catalog-filters-1.0.min.js — нет. Стили приезжают заранее, код — по
действию посетителя. Скачали копию, не открывая фильтр, — получили оформление
фильтра без фильтра.
Два имени, похожие на файлы, я из этого списка исключил, и обе причины стоит знать, если будете считать сами:
tilda-blocks-2.7— не загрузка, а проба. Код анимации ищетdocument.querySelector('script[src*="tilda-blocks-2.7"]'), то есть проверяет, подключён ли старый файл блоков, и ведёт себя по-разному.tilda-form-1.0— не файл, а значение поляfilenameв объекте ошибки, который Тильда кладёт вwindow.t_jserrors.
Адрес не лежит в HTML — он вычисляется
Две функции из tilda-scripts-3.0 объясняют, почему поиск по разметке не находит
все обращения к Тильде:
function t_getRootZone() {
var t = document.getElementById("allrecords"), e;
return t && t.getAttribute("data-tilda-root-zone") || "com"
}
function t_modifyRootZone(t) {
return t && t.includes("static.tildacdn.com")
? t.replace("static.tildacdn.com", "static.tildacdn." + t_getRootZone())
: t
}
t_modifyRootZone вызывается ровно в двух местах — в начале t_loadJsFile и в
начале t_loadCSSFile, то есть на каждой догрузке файла. Обратите внимание на
условие: функция трогает только строки, в которых есть static.tildacdn.com. Чужой
домен она не переписывает — подставите свой адрес, код его оставит. Это важно:
механизм не мешает переносу, он лишь показывает, что хост вычисляется в браузере, а
не хранится в разметке.
У загрузчика есть ещё деталь, которую видно только в коде:
function t_loadJsFile(t, e, n) {
void 0 === n && (n = 0);
var o = 3, i = 1e3, r = t_modifyRootZone(t);
// ...
// при ошибке: a.remove(), t_loadJsFile(r, e, n + 1),
// console.warn("Retrying to load " + r + ". Retry: " + (n + 1))
}
Три попытки с задержкой 1000 мс, и в консоль пишется Retrying to load …. Если в
скопированной версии сайта в консоли появляется такая строка — это как раз попытка
догрузить файл, которого в копии нет.
Десять служб, которые не скачиваются
Файл можно положить рядом. Адрес, к которому код обращается за данными, положить рядом нельзя:
| Служба | Адрес в коде | Как задан |
|---|---|---|
| Отправка формы | forms.tildacdn.com, а при зоне — forms.tildaapi.<зона> | значение свойства при инициализации |
| Капча в форме | тот же адрес, iframe /procces/captcha/ | собирается из свойства |
| Брошенная корзина | forms.tildacdn.com/api/v1/getlostbasket/ | зашит целиком |
| Расчёт доставки | delivery.tildacdn.com | сравнение с ".tildacdn.com" в коде |
| Геосервис | geoserv.tildacdn.com | строка "https://geoserv" плюс хвост |
| Кабинет покупателя | members2.tildacdn.com либо members.tildaapi.<зона> | выбор по атрибуту зоны |
| Файлы кабинета | тот же адрес плюс /frontend/js/ | склеивается с endpoint |
| Спасательный код | neo.tildacdn.com | зашит, зона не подставляется |
| Оптимизатор картинок | optim.tildacdn.<зона>, у отдельного файла thumb.tildacdn.com | подмена домена в браузере |
| Сторож в избранном | tildacdn.com и tildacdn.info | проверка вхождения подстроки |
Что делает каждый из этих адресов и как рантайм собирает их из строки и зоны — разобрано отдельно в «static.tildacdn.com». Здесь важно другое: ни один из них нельзя положить рядом с файлами.
Две вещи из этой таблицы стоит развернуть, потому что они меняют картину.
Адрес формы может переназначить сервер. Обычно endpoint задаётся один раз, но в
ответе на отправку формы Тильда может прислать поле redirectto длиной три символа
— и клиент переназначит собственный адрес и отправит форму заново:
if (objData && objData.redirectto && 3 == objData.redirectto.length
&& window.tildaForm.endpoint.substring(window.tildaForm.endpoint.length - 3) != objData.redirectto)
return window.tildaForm.endpoint = "forms.tildaapi." + objData.redirectto,
window.tildaForm.send(form, btnSubmit, formType, formKey), !1
Всего window.tildaForm.endpoint читается 10 раз и присваивается 3 раза. То есть
адрес отправки — не константа, а состояние, которым управляет и код страницы, и
ответ сервера.
Картинки на своём домене теряют функции молча. Оптимизатор подменяет домен
только у адресов с static.tildacdn., а избранное принимает картинку товара только
с двух доменов:
"image" == p[0] && (p[1].indexOf("tildacdn.com") > 0
|| p[1].indexOf("tildacdn.info") > 0) && (i = p[1])
Переложили картинки на свой хостинг — превью в избранном перестанут появляться, и ошибки при этом не будет: условие просто не выполнится.
Одна ветка в пользу переноса
Она стоит последней строкой в window.tildaForm.send:
return -1 == form.getAttribute("action").indexOf(window.tildaForm.endpoint)
&& (t_removeClass(btnSubmit, "t-btn_sending"),
btnSubmit.tildaSendingStatus = "3",
form.submit(), !0)
Читается так: если в атрибуте action формы нет домена Тильды, скрипт снимает
с кнопки состояние отправки и вызывает нативный form.submit() — обычную отправку
браузером на тот адрес, который указан в action.
Оговорка обязательна: это чтение одной строки, а не проверенный сценарий. Строка стоит в конце функции, и до неё доходит не каждый путь исполнения. Проверять на своём обработчике придётся вам. Но сама ветка означает, что переназначение формы код предусматривает, а не блокирует.
Три сценария и что в каждом остаётся
О принимающих площадках я ничего не утверждаю — не мерил их. Утверждаю только то, что видно в коде страницы, и это одинаково для любого получателя.
«Сохранить страницу как» из браузера. Уедет разметка, стили и то, что уже загрузилось. Не уедут 25 файлов из раздела выше: браузер сохраняет то, что было запрошено, а они запрашиваются по действию посетителя.
Скачать всё из панели разработчика на свой хостинг. Уедет больше — 31 файл кода
и 7 картинок. Но останутся десять служб из таблицы, и вести себя они будут
по-разному: форма продолжит отправляться на Тильду, пока не поменяете action;
доставка и брошенная корзина будут стучаться на её адреса; кабинет покупателя
попытается загрузить свои файлы с members-адреса.
Перенос на другую платформу. Здесь важно понимать, что именно переносится:
разметка Тильды не самостоятельна. Работу страницы обеспечивают 31 файл её кода
плюс те, что догружаются; вёрстка построена на её классах и её сетке
(tilda-grid-3.0.min.css). Перенести «страницу» и перенести «страницу вместе с её
поведением» — разные объёмы работы, и второй ближе к переделке, чем к переносу.
Честно о том, кто это пишет
Мы делаем доработки для Тильды, то есть заинтересованы в обратном — чтобы вы
остались. Поэтому здесь нет ни одного аргумента «зачем оставаться»: только замеры
из HTML страницы и из 53 файлов рантайма, с указанием, что именно измерено и где.
Числа проверяемы: откройте панель разработчика на своей странице и пересчитайте
src= и href= на домен Тильды — только не забудьте про одинарные кавычки, на
которых я сам сначала потерял четыре картинки.
Если из этого текста вывод получается «переносить дорого, а не хватает одной функции» — это как раз наш случай: доработка бэкенда и личный кабинет закрывают то, ради чего чаще всего затевают переезд. Если вывод другой — статья всё равно сделала свою работу.