В наше время современных браузеров с поддержкой HTML5, WebSocket и Full Ajax приложений больше нет необходимости забивать backend-сервера чем-то отличным от бизнес логики. Вся ui-разработка может вестись на nginx сервере с заглушками api сервисов. А фреймворки для авто-генерации документации помогут и ui, и backend разработчикам снизить затраты на коммуникацию. Передача одних лишь json данных также существенно снизит нагрузку на сервера. Ведь сжатый javascript код ui-клиента можно держать в кеше приложения.
Но если современные бразуеры с легкостью справятся с возросшей ответственностью, то поисковым системам нужна помощь.
Для правильной индексации приложения на angularjs нам понадобятся следующие вещи:
- sitemap.xml
- html5Mode
- nginx
- old fashion backend server
HTML5 mode
Html5 mode превращает angularjs routes из вида example.com/#!/home
в вид example.com/home
(все href
ссылки должны также указывать на url без hashbang). Чтобы включить html5mode нужно выполнить:
$locationProvider.html5Mode(true); $locationProvider.hashPrefix('!');
я оставляю !
для совместимости с браузерами, не поддерживающими javascript
Теперь необходимо чтобы наш nginx сервер отправлял запросы с example.com/home
на главный index.html
файл приложения. Для этого укажем в конфиге следующую директиву:
location / { expires -1; add_header Pragma "no-cache"; add_header Cache-Control "no-store, no-cache, must-revalidate, post-check=0, pre-check=0"; root /var/web; try_files $uri $uri/ /index.html =404; }
Строка try_files $uri $uri/ /index.html =404;
означает что теперь все несуществующие url будут переадресованы на index.html
файл, сохранив при этом url в адресной строке браузера.
Это решение уже является рабочим (а также совместимым с старым hashbang форматом ссылок) и если ваше приложение не должно индексироваться поисковыми системами то можно закончить.
SEO
Теперь поможем поисковику обработать наше приложение правильно. Для этого мы подготовим подсказки для бота и сгенерируем snapshot страниц. Для начала расскажем ему о том, какие страницы нужно индексировать с помощью sitemap.xml
файла. Простейший вариант файла состоит из ссылок на страницы и даты их последнего обновления (более подробный формат есть на сайте www.sitemaps.org/):
<urlset xmlns='http://www.sitemaps.org/schemas/sitemap/0.9'> <url> <loc>http://senior-java-developer.com/java/basics</loc> <lastmod>2013-07-12</lastmod> </url> <url> <loc>http://senior-java-developer.com/</loc> <lastmod>2013-07-12</lastmod> </url> </urlset>
Отлично, поисковик будет запрашивать ссылки нашего сайта и получать контент index.html
т.к. никакой обработки javascript в поисковые боты не встроено. Расскажем боту что за технической страницей `index.html` спрятан реальный контент. Для этого в заголовок страницы добавим:
<meta name="fragment" content="!" />
Это даст боту возможность сделать следующий шаг. Увидев fragmet=!
бот запросит страницу еще раз, но добавит в конец url параметр ?_escaped_fragment_=
. Подскажем nginx что запросы с данным параметром нужно отправлять в другое место:
if ($args ~ "_escaped_fragment_=(.*)") { rewrite ^ /snapshot${uri}; } location /snapshot { proxy_pass http://api; proxy_connect_timeout 60s; }
Вот и все, теперь все запросы от бота будут отправлены к api backend серверу.
Real url | Bot url | Backend url |
example.com |
example.com/?_escaped_fragment_= |
localhost:8080/snapshot/ |
example.com/home |
example.com/home?_escaped_fragment_= |
localhost:8080/snapshot/home |
Для формирования снапшота я использую thymeleaf. Т.к. и thymeleaf, и angularjs используют html5 атрибуты можно использовать единый файл шаблона, однако я предпочитаю не смешивать их.
Строчка из html view выглядела бы примерно так:
<div ng-bind="text" th:text="${text}"></div>
ссылка на оригинал статьи http://habrahabr.ru/post/187008/
Добавить комментарий