Применение одной страницы ( SPA ) представляет собой веб - приложение или веб - сайт , который взаимодействует с пользователем посредством динамической перезаписи текущей веб - страницы с новыми данными с веб - сервера , вместо метода по умолчанию через веб - браузер загрузки целых новых страниц. Цель быстрее переходы , которые делают сайт чувствовать себя больше как родное приложение .
В SPA обновление страницы никогда не происходит; вместо этого весь необходимый код HTML , JavaScript и CSS либо извлекается браузером при загрузке одной страницы [1], либо соответствующие ресурсы динамически загружаются и добавляются на страницу по мере необходимости, обычно в ответ на действия пользователя. Страница не перезагружается ни на каком этапе процесса и не передает управление другой странице, хотя хэш местоположения или API истории HTML5 можно использовать для обеспечения восприятия и навигации по отдельным логическим страницам в приложении. [2]
История
Происхождение термина « одностраничное приложение» неясно, хотя эта концепция обсуждалась, по крайней мере, еще в 2003 году. [3] Стюарт Моррис, студент-программист в Кардиффском университете, Уэльс, написал автономный веб-сайт на slashdotslash.com с те же цели и функции в апреле 2002 г. [4] и позже в том же году Лукас Бирдо, Кевин Хакман, Майкл Пичи и Клиффорд Йе описали реализацию одностраничного приложения в патенте США 8,136,109. [5]
JavaScript можно использовать в веб-браузере для отображения пользовательского интерфейса (UI), запуска логики приложения и связи с веб-сервером. Доступны зрелые библиотеки с открытым исходным кодом, которые поддерживают создание SPA, что сокращает объем кода JavaScript, который приходится писать разработчикам.
Технические подходы
Существуют различные доступные методы, позволяющие браузеру сохранять одну страницу, даже если приложению требуется связь с сервером.
Хэши документов
Авторы HTML могут использовать идентификаторы элементов, чтобы отображать или скрывать различные разделы документа HTML. Затем, используя CSS, авторы могут использовать селектор `# target`, чтобы отображать только тот раздел страницы, к которому перешел браузер.
Фреймворки JavaScript
Фреймворки и библиотеки JavaScript веб-браузера, такие как AngularJS , Ember.js , ExtJS , Knockout.js , Meteor.js , React , Vue.js и Svelte , приняли принципы SPA. Помимо ExtJS, все они имеют открытый исходный код .
- AngularJS - это полностью клиентский фреймворк. Шаблоны AngularJS основаны на двунаправленной привязке данных пользовательского интерфейса . Привязка данных - это автоматический способ обновления представления при изменении модели, а также обновления модели при изменении представления. HTML-шаблон компилируется в браузере. На этапе компиляции создается чистый HTML-код, который браузер повторно отображает в режиме реального времени. Этот шаг повторяется для последующих просмотров страницы. В традиционном серверном HTML-программировании такие концепции, как контроллер и модель, взаимодействуют внутри серверного процесса для создания новых HTML-представлений. В структуре AngularJS состояние контроллера и модели поддерживается в клиентском браузере. Следовательно, новые страницы могут быть созданы без какого-либо взаимодействия с сервером.
- Ember.js - это клиентская платформа веб-приложений JavaScript, основанная на архитектурном шаблоне программного обеспечения модель – представление – контроллер (MVC). Он позволяет разработчикам создавать масштабируемые одностраничные приложения путем включения общих идиом и передовых практик в структуру, которая предоставляет богатую объектную модель, декларативную двустороннюю привязку данных, вычисляемые свойства, автоматическое обновление шаблонов на основе Handlebars.js и маршрутизатор для управление состоянием приложения.
- ExtJS также является фреймворком на стороне клиента, который позволяет создавать приложения MVC. Он имеет собственную систему событий, управление окнами и макетом, управление состоянием (хранилища) и различные компоненты пользовательского интерфейса (сетки, диалоговые окна, элементы форм и т. Д.). У него есть собственная система классов с динамическим или статическим загрузчиком. Приложение, созданное с помощью ExtJS, может существовать либо само по себе (с состоянием в браузере), либо с сервером (например, с REST API, который используется для заполнения его внутренних хранилищ). ExtJS имеет только встроенные возможности для использования localStorage, поэтому более крупным приложениям требуется сервер для хранения состояния.
- Knockout.js - это фреймворк на стороне клиента, который использует шаблоны на основе шаблона Model-View-ViewModel .
- Meteor.js - это полнофункциональный (клиент-серверный) JavaScript-фреймворк, разработанный исключительно для SPA. Он имеет более простую привязку данных, чем Angular, Ember или ReactJS [6], и использует протокол распределенных данных [7] и шаблон публикации-подписки для автоматического распространения изменений данных клиентам в режиме реального времени, не требуя от разработчика написания кода синхронизации. . Реактивность полного стека гарантирует, что все слои, от базы данных до шаблонов, обновляются автоматически при необходимости. Пакеты экосистемы, такие как рендеринг на стороне сервера [8], решают проблему поисковой оптимизации.
- React - это библиотека JavaScript для создания пользовательских интерфейсов . Он поддерживается Facebook , Instagram и сообществом отдельных разработчиков и корпораций. React использует новый язык, который представляет собой смесь JS и HTML (подмножество HTML). Несколько компаний используют React с Redux (библиотека JavaScript), которая добавляет возможности управления состоянием, что (вместе с несколькими другими библиотеками) позволяет разработчикам создавать сложные приложения. [9]
- Vue.js - это JavaScript-фреймворк для создания пользовательских интерфейсов. Разработчики Vue также предоставляют Vuex для управления состоянием.
- Svelte - это фреймворк для создания пользовательских интерфейсов, который компилирует код Svelte для манипуляций с DOM JavaScript, избегая необходимости связывать фреймворк с клиентом и позволяя упростить синтаксис разработки приложений.
Аякс
По состоянию на 2006 год наиболее известной используемой техникой был Ajax . [1] Ajax предполагает использование асинхронных запросов к серверу для данных XML или JSON , например, с помощью JavaScript XMLHttpRequest или более современного fetch () (с 2017 года) или устаревшего объекта ActiveX . В отличие от декларативного подхода большинства фреймворков SPA, с Ajax веб-сайт напрямую использует JavaScript или библиотеку JavaScript, такую как jQuery, для управления DOM и редактирования элементов HTML. В дальнейшем Ajax был популяризирован такими библиотеками, как jQuery , которые обеспечивают более простой синтаксис и нормализуют поведение Ajax в разных браузерах, которые исторически имели разное поведение.
WebSockets
WebSockets - это технология двунаправленной связи клиент-сервер в реальном времени, которая является частью спецификации HTML5. Для связи в реальном времени их использование превосходит Ajax с точки зрения производительности [10] и простоты.
Отправленные сервером события
Отправленные сервером события (SSE) - это метод, с помощью которого серверы могут инициировать передачу данных клиентам браузера. После того, как начальное соединение установлено, поток событий остается открытым, пока не будет закрыт клиентом. SSE отправляются по традиционному протоколу HTTP и имеют множество функций, которые отсутствуют в WebSockets по своей конструкции, такие как автоматическое переподключение, идентификаторы событий и возможность отправлять произвольные события. [11]
Плагины браузера
Хотя этот метод устарел, асинхронные вызовы сервера также могут быть выполнены с использованием технологий подключаемых модулей браузера, таких как Silverlight , Flash или Java-апплеты .
Транспорт данных (XML, JSON и Ajax)
Запросы к серверу обычно приводят либо к необработанным данным (например, XML или JSON ), либо к возвращению нового HTML . В случае, когда сервер возвращает HTML, JavaScript на клиенте обновляет частичную область DOM ( объектной модели документа ). [12] Когда необработанные данные возвращаются, часто клиентский процесс JavaScript XML / ( XSL ) (а в случае JSON - шаблон ) используется для преобразования необработанных данных в HTML, который затем используется для обновления частичной области. ДОМ.
Архитектура сервера
Архитектура тонкого сервера
SPA перемещает логику с сервера на клиент, при этом роль веб-сервера превращается в API чистых данных или веб-службу. Этот архитектурный сдвиг в некоторых кругах был назван «архитектурой тонкого сервера», чтобы подчеркнуть, что сложность была перенесена с сервера на клиент, с аргументом, что это в конечном итоге снижает общую сложность системы.
Толстая серверная архитектура с отслеживанием состояния
Сервер сохраняет необходимое состояние в памяти о состоянии клиента страницы. Таким образом, когда какой-либо запрос попадает на сервер (обычно это действия пользователя), сервер отправляет соответствующий HTML и / или JavaScript с конкретными изменениями, чтобы привести клиента в новое желаемое состояние (обычно добавление / удаление / обновление части клиентский DOM). В то же время состояние на сервере обновляется. Большая часть логики выполняется на сервере, и HTML обычно также отображается на сервере. В некотором смысле сервер имитирует веб-браузер, получая события и выполняя дельта-изменения в состоянии сервера, которые автоматически передаются клиенту.
Для этого подхода требуется больше серверной памяти и серверной обработки, но преимуществом является упрощенная модель разработки, потому что а) приложение обычно полностью закодировано на сервере, и б) данные и состояние пользовательского интерфейса на сервере совместно используются в одном пространстве памяти без каких-либо ограничений. необходимость в настраиваемых мостах связи клиент / сервер.
Толстая архитектура сервера без сохранения состояния
Это вариант подхода к серверу с отслеживанием состояния. Клиентская страница отправляет данные, представляющие ее текущее состояние, на сервер, обычно через запросы Ajax. Используя эти данные, сервер может реконструировать состояние клиента той части страницы, которую необходимо изменить, и может сгенерировать необходимые данные или код (например, как JSON или JavaScript), который возвращается клиенту, чтобы принести его в новое состояние, обычно изменяя дерево DOM страницы в соответствии с действием клиента, которое мотивировало запрос.
Этот подход требует, чтобы на сервер было отправлено больше данных, и может потребоваться больше вычислительных ресурсов на запрос для частичного или полного восстановления состояния клиентской страницы на сервере. В то же время этот подход легче масштабируется, поскольку на сервере нет данных о странице для каждого клиента, и, следовательно, запросы Ajax могут быть отправлены на разные серверные узлы без необходимости совместного использования данных сеанса или привязки к серверу.
Работает локально
Некоторые SPA могут выполняться из локального файла с использованием схемы URI файла . Это дает пользователям возможность загружать SPA с сервера и запускать файл с локального запоминающего устройства, независимо от подключения к серверу. Если такой SPA хочет хранить и обновлять данные, он должен использовать веб- хранилище на основе браузера . Эти приложения извлекают выгоду из достижений HTML5 . [13]
Проблемы с моделью SPA
Поскольку SPA представляет собой эволюцию от модели перерисовки страниц без сохранения состояния, для которой изначально были разработаны браузеры, возникли некоторые новые проблемы. Возможные решения (различной сложности, полноты и авторского контроля) включают: [14]
- Клиентские библиотеки JavaScript.
- Серверные веб-фреймворки, специализирующиеся на модели SPA. [15] [16] [17]
- Развитие браузеров и спецификация HTML5 [18], разработанная для модели SPA.
Поисковая оптимизация
Из - за отсутствия исполнения JavaScript на гусеничном некоторых популярных веб - поисковых систем , [19] SEO ( Поисковая оптимизация ) исторически представляет собой проблему для веб - сайтов государственных облицовочных желающих принять модель SPA. [20]
В период с 2009 по 2015 год Центр веб-мастеров Google предложил, а затем рекомендовал «схему сканирования AJAX» [21] [22] с использованием начального восклицательного знака в идентификаторах фрагментов для страниц AJAX с отслеживанием состояния ( #!
). На сайте SPA должно быть реализовано специальное поведение, чтобы сканер поисковой системы мог извлекать релевантные метаданные. Для поисковых систем , которые не поддерживают этот URL хэш - схему, хэшированный URL - адрес из ВНСА остается невидимым. Многие авторы, в том числе Джени Теннисон из W3C, сочли эти URI "хэш-бэнг" проблемными, поскольку они делают страницы недоступными для тех, у кого в браузере не активирован JavaScript . Они также нарушают заголовки HTTP-рефералов, поскольку браузерам не разрешено отправлять идентификатор фрагмента в заголовке Referer. [23] В 2015 году Google отказался от предложения по сканированию с помощью hash-bang AJAX. [24]
В качестве альтернативы приложения могут отображать загрузку первой страницы на сервере и последующие обновления страницы на клиенте. Это традиционно сложно, потому что код рендеринга может быть написан на другом языке или на другом языке на сервере и на клиенте. Использование шаблонов без логики, кросс-компиляция с одного языка на другой или использование одного и того же языка на сервере и клиенте может помочь увеличить объем кода, который можно совместно использовать.
В 2018 году Google представил динамический рендеринг в качестве еще одного варианта для сайтов, желающих предложить сканерам тяжелую версию страницы без JavaScript для целей индексации. [25] Динамический рендеринг переключается между версией страницы, которая отображается на стороне клиента, и версией, предварительно отрисованной для определенных пользовательских агентов. Этот подход предполагает, что ваш веб-сервер обнаруживает поисковых роботов (через пользовательский агент) и направляет их в средство визуализации, из которого они затем получают более простую версию содержимого HTML.
Поскольку совместимость с SEO для SPA нетривиальна, стоит отметить, что SPA обычно не используются в контексте, когда индексация поисковой системы является обязательной или желательной. Сценарии использования включают приложения, которые отображают личные данные, скрытые за системой аутентификации . В случаях, когда эти приложения являются потребительскими продуктами, часто для целевой страницы приложений и маркетингового сайта используется классическая модель «перерисовки страницы», которая предоставляет достаточно метаданных для того, чтобы приложение появилось в качестве попадания в поисковом запросе. Блоги, форумы поддержки и другие традиционные артефакты перерисовки страниц часто располагаются вокруг SPA, которые могут заполнить поисковые системы соответствующими терминами.
Другой подход, используемый серверно-ориентированными веб-фреймворками, такими как ItsNat на основе Java, - это визуализация любого гипертекста на сервере с использованием того же языка и технологии шаблонов. В этом подходе сервер точно знает состояние DOM на клиенте, любое требуемое большое или маленькое обновление страницы генерируется на сервере и транспортируется Ajax, точный код JavaScript для перевода клиентской страницы в новое состояние, выполняя методы DOM. . Разработчики могут решить, какие состояния страницы должны сканироваться веб-пауками для SEO, и иметь возможность генерировать необходимое состояние во время загрузки, генерируя простой HTML вместо JavaScript. В случае инфраструктуры ItsNat это происходит автоматически, потому что ItsNat хранит дерево DOM клиента на сервере как дерево DOM Java W3C; рендеринг этого дерева DOM на сервере генерирует простой HTML во время загрузки и действия JavaScript DOM для запросов Ajax. Эта двойственность очень важна для SEO, потому что разработчики могут создавать с помощью одного и того же кода Java и чистого HTML-шаблона, создавая желаемое состояние DOM на сервере; во время загрузки страницы ItsNat генерирует обычный HTML, что делает это состояние DOM SEO-совместимым.
Начиная с версии 1.3, [26] ItsNat предоставляет новый режим без сохранения состояния, и клиентская DOM не хранится на сервере, потому что с клиентом, работающим в режиме без сохранения состояния, состояние DOM частично или полностью восстанавливается на сервере при обработке любого запроса Ajax на основе необходимые данные, отправляемые клиентом, информирующие сервер о текущем состоянии DOM; режим без сохранения состояния может быть также совместим с SEO, поскольку совместимость с SEO происходит во время загрузки начальной страницы, на которую не влияют режимы с сохранением состояния или без состояния. Другой возможный выбор - такие фреймворки, как PreRender, Puppeteer, Rendertron, которые можно легко интегрировать в любой веб-сайт в качестве промежуточного программного обеспечения с конфигурацией веб-сервера, позволяющей обрабатывать запросы ботов (бот Google и другие) с помощью промежуточного программного обеспечения, в то время как запросы, не относящиеся к ботам, обслуживаются как обычно . Эти фреймворки периодически кэшируют соответствующие страницы веб-сайтов, чтобы последние версии были доступны поисковым системам. Эти фреймворки официально одобрены Google. [27]
Есть несколько обходных путей, которые позволяют сделать вид, что веб-сайт доступен для сканирования. Оба включают создание отдельных HTML-страниц, которые отражают содержимое SPA. Сервер может создать версию сайта на основе HTML и доставить ее сканерам, или можно использовать автономный браузер, такой как PhantomJS, для запуска приложения JavaScript и вывода полученного HTML.
И то, и другое требует значительных усилий и в конечном итоге может вызвать головную боль при обслуживании больших сложных сайтов. Есть также потенциальные подводные камни SEO. Если HTML-код, сгенерированный сервером, будет слишком отличаться от содержимого SPA, сайт будет оштрафован. Запуск PhantomJS для вывода HTML может замедлить скорость отклика страниц, для чего поисковые системы, в частности Google, понижают рейтинг. [28]
Разделение клиент-серверного кода
Один из способов увеличить объем кода, который может быть разделен между серверами и клиентами, - это использовать язык шаблонов без логики, такой как Mustache или Handlebars . Такие шаблоны могут отображаться на разных языках хоста, таких как Ruby на сервере и JavaScript на клиенте. Однако простое совместное использование шаблонов обычно требует дублирования бизнес-логики, используемой для выбора правильных шаблонов и заполнения их данными. Отрисовка из шаблонов может иметь отрицательное влияние на производительность при обновлении только небольшой части страницы, например значения ввода текста в большом шаблоне. Замена всего шаблона также может нарушить выбор пользователя или положение курсора, тогда как обновление только измененного значения может не измениться. Чтобы избежать этих проблем, приложения могут использовать привязки данных пользовательского интерфейса или детализированные манипуляции с DOM, чтобы обновлять только соответствующие части страницы, вместо повторного рендеринга целых шаблонов.
История браузера
Поскольку SPA по определению является «отдельной страницей», модель нарушает дизайн браузера для навигации по истории страниц с использованием кнопок «вперед» или «назад». Это представляет собой препятствие для удобства использования, когда пользователь нажимает кнопку «Назад», ожидая предыдущего состояния экрана в SPA, но вместо этого выгружается отдельная страница приложения и отображается предыдущая страница в истории браузера.
Традиционным решением для SPA было изменение идентификатора хэш- фрагмента URL-адреса браузера в соответствии с текущим состоянием экрана. Это может быть достигнуто с помощью JavaScript и вызывает создание событий истории URL в браузере. Пока SPA способен восстанавливать одно и то же состояние экрана из информации, содержащейся в хэше URL-адреса, ожидаемое поведение кнопки возврата сохраняется.
Для дальнейшего решения этой проблемы в спецификации HTML5 были введены pushState и replaceState, обеспечивающие программный доступ к фактическому URL-адресу и истории браузера.
Аналитика
Инструменты аналитики, такие как Google Analytics, в значительной степени полагаются на загрузку целых новых страниц в браузере, инициированную загрузкой новой страницы. СПА так не работают.
После загрузки первой страницы все последующие изменения страниц и содержимого обрабатываются внутри приложения, которое должно просто вызвать функцию для обновления пакета аналитики. Без вызова указанной функции браузер никогда не запускает новую загрузку страницы, ничего не добавляется в историю браузера, а пакет аналитики не знает, кто что делает на сайте.
Сканирование безопасности
Подобно проблемам, с которыми сталкиваются сканеры поисковых систем, инструменты DAST могут бороться с этими приложениями, богатыми JavaScript. Проблемы могут включать в себя отсутствие гипертекстовых ссылок, использование памяти и ресурсов, загружаемых SPA, которые обычно становятся доступными через интерфейс прикладного программирования или API. Одностраничные приложения по-прежнему подвержены тем же рискам безопасности, что и традиционные веб-страницы, такие как межсайтовые сценарии (XSS) , но также подвержены множеству других уникальных уязвимостей, таких как раскрытие данных через API и клиентская логика и принудительное применение сервера на стороне клиента. -Боковая охрана. [29] Чтобы эффективно сканировать одностраничное приложение, сканер DAST должен иметь возможность перемещаться по клиентскому приложению надежным и повторяемым образом, чтобы обеспечить обнаружение всех областей приложения и перехват всех запросов, отправляемых приложением. к удаленным серверам (например, запросы API). Есть несколько коммерческих инструментов, способных на такие действия, но такие инструменты определенно существуют.
Добавление загрузки страницы в SPA
Можно добавить события загрузки страницы в SPA с помощью API истории HTML5; это поможет интегрировать аналитику. Сложность заключается в том, чтобы справиться с этим и обеспечить точное отслеживание всего - это включает проверку отсутствующих отчетов и двойных записей. Некоторые фреймворки обеспечивают интеграцию аналитики с открытым исходным кодом, адресованную большинству основных поставщиков аналитики. Разработчики могут интегрировать их в приложение и убедиться, что все работает правильно, но нет необходимости делать все с нуля. [28]
Ускорение загрузки страницы
Есть несколько способов ускорить начальную загрузку SPA, например усиленный подход к кешированию и отложенная загрузка модулей при необходимости. Но невозможно уйти от того факта, что ему необходимо загрузить фреймворк, по крайней мере, часть кода приложения, и, скорее всего, он будет обращаться к API для данных перед отображением чего-либо в браузере. [28] Это компромиссный сценарий «заплати мне сейчас или заплати позже». Вопрос производительности и времени ожидания остается решением, которое должен принять разработчик.
Жизненный цикл страницы
SPA полностью загружается при начальной загрузке страницы, а затем области страницы заменяются или обновляются новыми фрагментами страницы, загружаемыми с сервера по запросу. Чтобы избежать чрезмерной загрузки неиспользуемых функций, SPA часто будет постепенно загружать дополнительные функции по мере необходимости, либо небольшие фрагменты страницы, либо полные модули экрана.
Таким образом, существует аналогия между «состояниями» в SPA и «страницами» на традиционном веб-сайте. Поскольку «навигация по состояниям» на той же странице аналогична навигации по страницам, теоретически любой страничный веб-сайт может быть преобразован в одностраничный, заменяя на той же странице только измененные части.
Подход SPA в Интернете аналогичен методу представления однодокументного интерфейса (SDI), популярному в собственных настольных приложениях.
Смотрите также
- Прогрессивное веб-приложение (PWA)
Рекомендации
- ^ a b Фланаган, Дэвид, " JavaScript - окончательное руководство ", 5-е изд., О'Рейли, Севастополь, Калифорния, 2006 г. , стр. 497
- ^ «Исправление кнопки« Назад »: поведение SPA с использованием хэша местоположения» . Блог программного обеспечения Falafel . Проверено 18 января, 2016 .
- ^ «Внутренний просмотр: расширение парадигмы навигации в Интернете» . Проверено 3 февраля 2011 года .
- ^ «Slashdotslash.com: автономный веб-сайт, использующий DHTML» . Проверено 6 июля 2012 года .
- ^ «Патент США 8,136,109» . Проверено 12 апреля 2002 года .
- ^ «Пламя метеора» .
Meteor Blaze - мощная библиотека для создания пользовательских интерфейсов, обновляемых в реальном времени. Blaze выполняет те же функции, что и Angular, Backbone, Ember, React, Polymer или Knockout, но его гораздо проще использовать. Мы создали его, потому что думали, что другие библиотеки делают программирование пользовательского интерфейса излишне сложным и запутанным.
- ↑ Представляем DDP , 21 марта 2012 г.
- ^ «Рендеринг на стороне сервера для Meteor» . Архивировано из оригинала 20 марта 2015 года . Проверено 31 января 2015 года .
- ^ «Одностраничные приложения против многостраничных приложений: плюсы, минусы, подводные камни - BLAKIT - IT Solutions» . blak-it.com . БЛАКИТ - ИТ-решения. 17 октября 2017 года . Проверено 19 октября 2017 года .
- ^ «Мониторинг в реальном времени с использованием AJAX и WebSockets» . www.computer.org . Проверено 1 июня 2016 года .
- ^ «События, отправленные сервером» . W3C. 17 июля 2013 г.
- ^ «Использование InnerHTML» . www.webrocketx.com . Проверено 21 января 2016 года .
- ^ «Неопубликованные веб-приложения» .
- ^ «Манифест одностраничного интерфейса» . Проверено 25 апреля 2014 года .
- ^ «Дерби» . Проверено 11 декабря 2011 года .
- ^ "Sails.js" . Проверено 20 февраля 2013 года .
- ^ «Учебное пособие: веб-сайт с одностраничным интерфейсом и ItsNat» . Проверено 13 января 2011 года .
- ^ HTML5
- ^ «Что видит пользователь, что видит краулер» . Проверено 6 января 2014 года .
браузер может выполнять JavaScript и создавать контент на лету - сканер не может
- ^ «Сделать приложения Ajax доступными для сканирования» . Проверено 6 января 2014 года .
Исторически сложилось так, что поисковым системам было сложно обрабатывать приложения Ajax, поскольку создается контент Ajax.
- ^ «Предложение сделать AJAX доступным для сканирования» . Google. 7 октября 2009 . Проверено 13 июля 2011 года .
- ^ «(Технические характеристики) Обеспечение возможности сканирования приложений AJAX» . Google . Проверено 4 марта 2013 года .
- ^ «URI хэша» . Блог W3C . 12 мая 2011 . Проверено 13 июля 2011 года .
- ^ «Прекращение поддержки нашей схемы сканирования AJAX» . Официальный блог Центра веб-мастеров Google . Проверено 23 февраля 2017 года .
- ^ «Реализовать динамический рендеринг» . Центр поиска Google . 13 октября 2018 . Проверено 7 января 2021 года .
- ^ «Примечания к выпуску ItsNat v1.3» . Проверено 9 июня 2013 года .
- ^ https://developers.google.com/search/docs/guides/dynamic-rendering
- ^ a b c Холмс, Симона (2015). Получение MEAN с помощью Mongo, Express, Angular и Node . Публикации Мэннинга. ISBN 978-1-6172-9203-3
- ^ «Одностраничные приложения (SPA)» . Appcheck Ltd .
Внешние ссылки
- Перенос многостраничных веб-приложений на одностраничные интерфейсы Ajax (Технологический университет Делфта)
- Манифест одностраничного интерфейса
- Динамический рендеринг