Замаскированная система рендеринга на стороне сервера

Node.js JavaScript

С момента разработки интерфейса и до настоящего времени SPA должен был широко использоваться. К сожалению, мы движемся быстро, и другие сканеры поисковых систем и браузеры пользователей не поспевают за нами. Одностраничное приложение, написанное с таким усердием, оказалось ошеломленным, когда дело дошло до SEO-совместимости с браузерами.

Многие студенты, должно быть, задумывались о проблеме рендеринга на стороне сервера. Однако, если вы посмотрите на документацию vue и отреагируете на рендеринг на стороне сервера, вас могут обмануть. То, что было написано ранее, не мигрирует без проблем. Более того, всякий раз, когда есть проект, вам нужно запускать набор сервисов узла. Конечно, друзья с лучшими архитектурными способностями могут неплохо справиться с централизованным управлением.

Поэтому, когда я хочу использовать vue или react в проекте, я сталкиваюсь с этими очень большими сопротивлениями. Пока у меня болела голова, я открыл для себя новый способ.

Не так давно мои коллеги поделились в группеpuppeteer, его описание на GitHub выглядит следующим образом:

Puppeteer is a Node library which provides a high-level API to control headless Chrome over the DevTools Protocol. It can also be configured to use full (non-headless) Chrome.

Например, библиотека узлов, предоставляющая API-интерфейсы для работы с Headless Chrome.

В частности, в среде узла через некоторые API-интерфейсы для «симуляции» реальных страниц доступа к Chrome, а также для имитации пользовательских операций, получения DOM и т. д.

Итак, поскольку он может получить доступ к странице, как настоящий Chrome, и вывести обработанный html, почему я не могу использовать его для рендеринга на стороне сервера для нас?

Представим, что у нас есть такой сервис А, который может обращаться к указанной странице как хром и возвращать вам дом на конечной странице.

Что касается вашего исходного бизнес-сервера B, вам нужно только решить, что это сканер или младшая версия IE, чтобы получить доступ, вызвать службу, получить html и вернуть html пользователю, который реализует рендеринг на стороне сервера. Общая блок-схема выглядит следующим образом:

После того, как у нас появилась такая идея, мы пытаемся найти способ воплотить ее в жизнь. Процесс практики – это процесс решения проблем. Если хорошенько подумать, то мы столкнемся со следующими проблемами:

Q1: Даже при имитации Chrome для запроса страницы во многих случаях представление отображается асинхронно. Например, сначала запросите интерфейс списка, получите данные, а затем отобразите DOM списка. На этот раз у нас нет возможности контролировать. Итак, когда эта служба должна вернуть загруженный HTML?

При возникновении проблем первым делом смотрите чужие документыPuppeteer API. К счастью, мы нашли следующие способы:

page.waitFor(selectorOrFunctionOrTimeout[, options[, ...args]])
page.waitForFunction(pageFunction[, options[, ...args]])
page.waitForNavigation(options)
page.waitForSelector(selector[, options])

Мы можем сделать страницу возвращать только при определенных условиях через некоторые настройки. Например, настройкаpage.waitForSelector('#app'), сделать так, чтобы страница отображаласьid="app", вернуть только содержимое html.

или установивpage.waitForFunction('window.innerWidth < 100'), Когда ширина страницы меньше 100 пикселей, возвращается html-контент в это время.

С помощью этих методов мы можем контролировать, когда и какие страницы мы хотим потерять для сканеров.

Q2: Что делать, если пользователи IE имеют большое количество посещений. Хотя мы используем такую ​​систему, некоторые браузеры (ниже IE9), которые не могут отображать страницу, могут ее отображать. Но такой процесс запроса занимает относительно больше времени, что не очень разумно.

Тогда у нас есть просто система кэширования. Каждый запрос должен определить, есть ли в этом запросе неиспользованный кеш HTML. Если есть, кеш HTML возвращается напрямую, в противном случае страница запроса будет запрошена для сохранения кеша.

Q3: Хотя страница отсутствует, пользователи IE по-прежнему не могут взаимодействовать с JS.

Мы не можем решить эту проблему на сервисном уровне, но можем создавать более понятные интерактивные подсказки во внешнем интерфейсе. Если будет определено, что у пользователя установлена ​​устаревшая версия IE, появится небольшая подсказка, предлагающая пользователю загрузить лучший браузер, чтобы получить лучший опыт.

Q4: Маршрутизация одностраничных приложений в основном выполняется с привязками (режим хеширования), а параметры хеширования не могут быть получены сервером, поэтому нет возможности запросить правильную страницу.

Есть способ решить эту проблему, вы можете использовать маршрут режима истории HTML, напримерvue-router, то маршрутную ссылку лучше прописать в странице в режиме генерации тега + href, а неonclickПосле скачка js краулер может лучше всего просканировать всю страницу.

Когда все проблемы решены, мы можем приступить к реальному кодированию.

Хлопать, хлопать, хлопать, хлопать, хлопать, хлопать =>SSR-SERVICE

Итак, вот и все, менее чем за 200 строк кода мы реализовали обобщенное сервисно-ориентированное решение для рендеринга одностраничных приложений на стороне сервера.