Как поисковые системы работают с приложениями AngularJS?

Я вижу две проблемы с приложением AngularJS относительно поисковых систем и SEO:

1) Что происходит с пользовательскими тегами? Игнорируют ли поисковые системы весь контент в этих тегах? то есть предположим, что я

<custom>
  <h1>Hey, this title is important</h1>
</custom>

б <h1> индексироваться, несмотря на то, что внутри пользовательских тегов?


2) есть ли способ избежать поисковых систем индексирования {{}} Привязок буквально? т. е.

<h2>{{title}}</h2>

Я знаю, что могу что-то сделать как

<h2 ng-bind="title"></h2>

но что, если я действительно хочу, чтобы гусеничный "видеть" название? Это серверный единственное решение?

15 ответов


Обновление

Google искатели теперь выполняет javascript - вы можете использовать Инструменты Веб-Мастера Google чтобы лучше понять, как ваши сайты отображаются Google.

оригинальный ответ
Если вы хотите оптимизировать свое приложение для поисковых систем, к сожалению, нет возможности обслуживать предварительно отрисованную версию для искателя. Вы можете узнать больше о рекомендациях Google для ajax и JavaScript-тяжелые сайты здесь.

Если это вариант, я бы рекомендовал читать в этой статье о том, как сделать SEO для Angular с рендерингом на стороне сервера.

Я не уверен, что делает искатель, когда он встречает пользовательские теги.


используйте PushState и Precomposition

текущий (2015) способ сделать это с помощью метода JavaScript pushState.

PushState изменяет URL в верхней панели браузера без перезагрузки страницы. Скажем, у вас есть страница, содержащая вкладки. Вкладки скрывают и показывают содержимое, и содержимое вставляется динамически, либо с помощью AJAX, либо просто установив display:none и display:block, чтобы скрыть и показать правильное содержимое вкладки.

когда вкладки нажал, используйте pushState для обновления url-адреса в адресной строке. При отображении страницы, Используйте значение в адресной строке, чтобы определить, какие вкладки показывать. Угловая маршрутизация сделает это за вас автоматически.

Precomposition

есть два способа попасть в приложение PushState Single Page (SPA)

  1. через PushState, где пользователь щелкает ссылку PushState и содержимое AJAXed В.
  2. , нажав URL напрямую.

в первоначальный удар по сайту будет включать прямое попадание по URL-адресу. Последующие хиты будут просто AJAX в содержимом, поскольку PushState обновляет URL-адрес.

искатели собирают ссылки со страницы, а затем добавляют их в очередь для последующей обработки. Это означает, что для искателя каждое попадание на сервер является прямым попаданием, они не перемещаются через Pushstate.

Precomposition связывает начальную полезную нагрузку в первый ответ от сервера, возможно, как объект JSON. Это позволяет Поиск Движок для рендеринга страницы без выполнения вызова AJAX.

есть некоторые доказательства того, что Google может не выполнять запросы AJAX. Подробнее об этом здесь:

https://web.archive.org/web/20160318211223/http://www.analog-ni.co/precomposing-a-spa-may-become-the-holy-grail-to-seo

поисковые системы могут читать и выполнять JavaScript

Google уже некоторое время может анализировать JavaScript, поэтому они изначально разработан Chrome, чтобы действовать как полнофункциональный безголовый браузер для Google spider. Если ссылка имеет допустимый атрибут href, новый URL-адрес может быть проиндексирован. Делать больше нечего.

если нажатие на ссылку дополнительно вызывает вызов pushState, сайт может перемещаться пользователем через PushState.

поддержка поисковой системы для pushState URLs

PushState в настоящее время поддерживается Google и Bing.

Google

вот Мэтт Каттс отвечая на вопрос пола Айриша о PushState для SEO:

http://youtu.be/yiAF9VdvRPw

вот Google объявляет о полной поддержке JavaScript для паука:

http://googlewebmastercentral.blogspot.de/2014/05/understanding-web-pages-better.html

в результате Google поддерживает PushState и индексирует URL-адреса PushState.

см. также выборку Google webmaster tools как Googlebot. Вы увидите, что ваш JavaScript (включая Angular) выполнен.

Бинг

вот объявление Bing о поддержке довольно pushState URLs от марта 2013 года:

http://blogs.bing.com/webmaster/2013/03/21/search-engine-optimization-best-practices-for-ajax-urls/

Не используйте HashBangs #!

URL-адреса Hashbang были уродливым временным ограничением, требующим от разработчика предоставить предварительную версию сайта на специальном местоположение. Они все еще работают, но вам не нужно их использовать.

URL-адреса Hashbang выглядят следующим образом:

domain.com/#!path/to/resource

это будет в паре с метатегом такой:

<meta name="fragment" content="!">

Google не будет индексировать их в этой форме, а вместо этого вытащит статическую версию сайта из URL-адреса _escaped_fragments_ и индексирует это.

URL-адреса Pushstate выглядеть как обычный URL-адрес:

domain.com/path/to/resource

разница это угловой обрабатывает их для вас, перехватывая изменение в документ.место работы с ним в JavaScript.

если вы хотите использовать URL-адреса PushState (и вы, вероятно, это делаете), удалите все старые URL-адреса и метатеги хэш-стиля и просто включите режим HTML5 в своем блоке конфигурации.

тестирование сайта

Google Webmaster tools теперь содержит инструмент, который позволит вам получить URL-адрес как google, и визуализировать JavaScript как Google renders он.

https://www.google.com/webmasters/tools/googlebot-fetch

создание URL-адресов PushState в Angular

чтобы генерировать реальные URL-адреса в Angular, а не # prefixed, установите режим HTML5 на свой объект $locationProvider.

$locationProvider.html5Mode(true);

Сервер

поскольку вы используете реальные URL-адреса, вам нужно будет обеспечить, чтобы один и тот же шаблон (плюс некоторый предварительно составленный контент) был отправлен вашим сервером для всех допустимых URL-адресов. Как ты это делаешь? это зависит от архитектуры сервера.

Карта сайта

ваше приложение может использовать необычные формы навигации, например парить или свиток. Чтобы убедиться, что Google может управлять вашим приложением, я бы, вероятно, предложил создать sitemap, простой список всех URL-адресов, на которые реагирует ваше приложение. Вы можете поместить его в папку по умолчанию (/sitemap или / sitemap.xml), или расскажите об этом Google с помощью инструментов веб-мастера.

это хорошая идея, чтобы иметь sitemap в любом случае.

поддержка браузеров

Pushstate работает в IE10. В старых браузерах Angular автоматически возвращается к URL-адресам в стиле хэша

демо-страницы

следующего содержания отображается с помощью pushstate URL с precomposition:

http://html5.gingerhost.com/london

как можно проверить, на этой ссылке содержание индексируется и появляется в Google.

сервировочная 404 и 301 коды состояния заголовка

поскольку поисковая система всегда будет поражать ваш сервер для каждого запроса, вы можете обслуживать коды состояния заголовка с вашего сервера и ожидать, что Google их увидит.


давайте окончательно о AngularJS и SEO

Google, Yahoo, Bing и другие поисковые системы сканируют интернет традиционными способами, используя традиционные искатели. Они бегут!--19-->роботы которые сканируют HTML на веб-страницах, собирая информацию по пути. Они хранят интересные слова и ищут другие ссылки на другие страницы (эти ссылки, их количество и количество вступают в игру с SEO).

так почему бы поисковым системам не иметь дело с сайты javascript?

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

что можно с этим поделать?

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

если мы изменим нашу hashPrefix на #! а не просто #, то современные поисковые системы изменят запрос на использование _escaped_fragment_ вместо #!. (В режиме HTML5, то есть там, где у нас есть ссылки без хэш-префикса, мы можем реализовать эту же функцию, посмотрев на в нашем внутренний.)

то есть вместо запроса от обычного браузера, который выглядит так:

http://www.ng-newsletter.com/#!/signup/page

поисковая система будет искать страницы с:

http://www.ng-newsletter.com/?_escaped_fragment_=/signup/page

мы можем установить хэш-префикс наших угловых приложений, используя встроенный метод из ngRoute:

angular.module('myApp', [])
.config(['$location', function($location) {
  $location.hashPrefix('!');
}]);

и, если мы используем html5Mode, мы должны реализовать это с помощью мета-тега:

<meta name="fragment" content="!">

напоминание, мы можем установить html5Mode() С $location сервис:

angular.module('myApp', [])
.config(['$location', 
function($location) {
  $location.html5Mode(true);
}]);

обработка поисковой системы

у нас есть много возможностей определить, как мы будем иметь дело с фактической доставкой контента в поисковые системы в виде статического HTML. Мы можем сами разместить бэкэнд, мы можем использовать сервис для размещения бэкэнда для нас, мы можем использовать прокси для доставки контента и т. д. Давайте рассмотрим несколько вариантов:

резидентной

мы можем написать сервис для работы работе с обход нашего собственного сайта с помощью безголового браузера, такого как phantomjs или zombiejs, снимок страницы с визуализированными данными и сохранение его в виде HTML. Когда мы видим строку запроса ?_escaped_fragment_ в поисковом запросе мы можем доставить статический снимок HTML, который мы сделали страницы, вместо предварительно отображенной страницы только через JS. Это требует, чтобы у нас был бэкэнд, который доставляет наши страницы с условной логикой посередине. Мы можем использовать что-то вродепрерандер.Ио бэкэнд как отправная точка, чтобы запустить это сами. Конечно, нам все еще нужно обрабатывать проксирование и обработку фрагментов, но это хорошее начало.

с платной услугой

самый простой и быстрый способ получить контент в поисковике воспользоваться услугой Brombone, seo.js, seo4ajax, и прерандер.Ио являются хорошими примерами тех, которые будут размещать вышеуказанный рендеринг контента для вас. Это хороший вариант для тех случаев, когда мы не хотим иметь дело с запуском сервера/прокси. Кроме того, это обычно очень быстро.

для получения дополнительной информации об Angular и SEO, мы написали обширный учебник по нему в http://www.ng-newsletter.com/posts/serious-angular-seo.htmlи мы его еще больше в нашей книге ng-book: Полная книга об AngularJS. Проверьте это на ng-book.com.


вы действительно должны проверить учебник по созданию SEO-дружественного сайта AngularJS в год блога moo. Он проведет вас через все шаги, описанные в документации Angular. http://www.yearofmoo.com/2012/11/angularjs-and-seo.html

используя этот метод, поисковая система видит расширенный HTML вместо пользовательских тегов.


это радикально изменилось.

http://searchengineland.com/bing-offers-recommendations-for-seo-friendly-ajax-suggests-html5-pushstate-152946

Если вы используете: $locationProvider.html5Mode (true); вы готовы.

больше нет страниц рендеринга.


с тех пор, как был задан этот вопрос, многое изменилось. Теперь есть варианты, чтобы позволить Google индексировать ваш сайт AngularJS. Самый простой вариант, который я нашел, - использовать http://prerender.io бесплатный сервис, который будет генерировать crwalable страницы для вас и служить, что в поисковых системах. Он поддерживается практически на всех серверных веб-платформах. Я недавно начал использовать их, и поддержка тоже отличная.

У меня нет никаких принадлежность к ним, это исходит от счастливого пользователя.


собственный сайт Angular обслуживает упрощенный контент для поисковых систем:http://docs.angularjs.org/?_escaped_fragment_=/tutorial/step_09

скажем, ваше Угловое приложение потребляет узел.JS / Express-управляемый JSON api, например /api/path/to/resource. Возможно, вы могли бы перенаправить любые запросы с ?_escaped_fragment_ to /api/path/to/resource.html, и использовать содержание переговоров чтобы отобразить HTML-шаблон содержимого, а не возвращать данные JSON.

единственное, ваш угловой маршруты должны соответствовать 1: 1 с вашим REST API.

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

вместо этого, вы можете использовать совершенно другой набор маршрутов и контроллеров для вашего робота дружественного контента. Но тогда вы дублируете все свои маршруты и контроллеры AngularJS в Node/Express.

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


хорошую практику можно найти здесь:

http://scotch.io/tutorials/javascript/angularjs-seo-with-prerender-io?_escaped_fragment_=tag


на данный момент Google изменил свое предложение по обходу AJAX.

времена изменились. Сегодня, пока вы не блокируете Googlebot от обхода ваших файлов JavaScript или CSS, мы обычно можем визуализировать и понимать ваши веб-страницы, как современные браузеры.

tl; dr: [Google] больше не рекомендуют предложение обхода AJAX [Google], сделанное еще в 2009 году.


искомая спецификация Ajax Google, как указано в других ответах здесь, в основном является ответом.

Если вас интересует, как другие поисковые системы и социальные боты справляются с теми же проблемами, я написал состояние искусства здесь: http://blog.ajaxsnapshots.com/2013/11/googles-crawlable-ajax-specification.html

Я работаю на https://ajaxsnapshots.com, компания, которая реализует искомую спецификацию Ajax в качестве службы-информация в основе этого отчета лежат наблюдения из наших журналов.


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

FYI это решение также включает жестко закодированные резервные теги в случае, если Javascript не подхватывается искателем. Я явно не изложил его, но стоит отметить, что вы должны активировать режим HTML5 для правильной поддержки URL.

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

app.js

здесь можно указать пользовательские метаданные для каждого из ваших маршрутов (название, описание и т. д.)

$routeProvider
   .when('/', {
       templateUrl: 'views/homepage.html',
       controller: 'HomepageCtrl',
       metadata: {
           title: 'The Base Page Title',
           description: 'The Base Page Description' }
   })
   .when('/about', {
       templateUrl: 'views/about.html',
       controller: 'AboutCtrl',
       metadata: {
           title: 'The About Page Title',
           description: 'The About Page Description' }
   })

метаданные-службе.js (службу)

устанавливает пользовательские параметры метаданных или используйте значения по умолчанию как резервные.

var self = this;

// Set custom options or use provided fallback (default) options
self.loadMetadata = function(metadata) {
  self.title = document.title = metadata.title || 'Fallback Title';
  self.description = metadata.description || 'Fallback Description';
  self.url = metadata.url || $location.absUrl();
  self.image = metadata.image || 'fallbackimage.jpg';
  self.ogpType = metadata.ogpType || 'website';
  self.twitterCard = metadata.twitterCard || 'summary_large_image';
  self.twitterSite = metadata.twitterSite || '@fallback_handle';
};

// Route change handler, sets the route's defined metadata
$rootScope.$on('$routeChangeSuccess', function (event, newRoute) {
  self.loadMetadata(newRoute.metadata);
});

метасвойства.js (директива)

пакеты результатов службы метаданных для представления.

return {
  restrict: 'A',
  scope: {
    metaproperty: '@'
  },
  link: function postLink(scope, element, attrs) {
    scope.default = element.attr('content');
    scope.metadata = metadataService;

    // Watch for metadata changes and set content
    scope.$watch('metadata', function (newVal, oldVal) {
      setContent(newVal);
    }, true);

    // Set the content attribute with new metadataService value or back to the default
    function setContent(metadata) {
      var content = metadata[scope.metaproperty] || scope.default;
      element.attr('content', content);
    }

    setContent(scope.metadata);
  }
};

.HTML-код

В комплекте с жестко закодированными резервными тегами, упомянутыми ранее, для искателей, которые не могут подобрать Javascript.

<head>
  <title>Fallback Title</title>
  <meta name="description" metaproperty="description" content="Fallback Description">

  <!-- Open Graph Protocol Tags -->
  <meta property="og:url" content="fallbackurl.com" metaproperty="url">
  <meta property="og:title" content="Fallback Title" metaproperty="title">
  <meta property="og:description" content="Fallback Description" metaproperty="description">
  <meta property="og:type" content="website" metaproperty="ogpType">
  <meta property="og:image" content="fallbackimage.jpg" metaproperty="image">

  <!-- Twitter Card Tags -->
  <meta name="twitter:card" content="summary_large_image" metaproperty="twitterCard">
  <meta name="twitter:title" content="Fallback Title" metaproperty="title">
  <meta name="twitter:description" content="Fallback Description" metaproperty="description">
  <meta name="twitter:site" content="@fallback_handle" metaproperty="twitterSite">
  <meta name="twitter:image:src" content="fallbackimage.jpg" metaproperty="image">
</head>

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

надеюсь, что это помогает!


Используйте что-то вроде PreRender, он делает статические страницы вашего сайта, чтобы поисковые системы могли индексировать его.

здесь вы можете узнать, для каких платформ он доступен:https://prerender.io/documentation/install-middleware#asp-net


с помощью Angular Universal вы можете создавать целевые страницы для приложения, которые выглядят как полное приложение, а затем загружать свое Угловое приложение за ним.
Angular Universal генерирует чистые HTML - страницы без javascript на стороне сервера и обслуживает их пользователям без задержки. Таким образом, вы можете иметь дело с любым искателем, ботом и пользователем (у которых уже есть низкая скорость процессора и сети).Затем вы можете изменить их по ссылкам/кнопкам на угловой приложение, которое уже загружено за ним. Это решение рекомендовано официальным сайтом. - дополнительная информация о SEO и Angular Universal -


искатели (или боты) предназначены для обхода содержимого HTML веб-страниц, но из-за операций AJAX для асинхронной выборки данных это стало проблемой, поскольку требуется некоторое время, чтобы отобразить страницу и показать динамическое содержимое на ней. Аналогично,AngularJS также используйте асинхронную модель, которая создает проблему для искателей Google.

некоторые разработчики создают базовые html-страницы с реальными данными и обслуживают эти страницы со стороны сервера во время обхода. Мы можем отображать одни и те же страницы с помощью PhantomJS на служить стороне, которая имеет _escaped_fragment_ (потому что Google ищет #! в нашем сайте urls, а затем берет все после #! и добавляет его в _escaped_fragment_ параметр запроса). Для более подробной информации, пожалуйста, прочитайте это блог .


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

мое решение: to дайте искателю то, что искатель хочет:

вы должны подумать о том, чего хочет краулер, и дать ему только это.

совет не связывайтесь со спиной. Просто добавьте небольшой серверный вид спереди, используя тот же API