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

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

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

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

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


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

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

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

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

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

Ответы

Ответ 1

Обновление мая 2014 года

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

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

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

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

Ответ 2

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

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

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

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

Precomposition

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

  • Через PushState, где пользователь нажимает ссылку PushState, а содержимое - AJAXed.
  • Прямая ссылка на URL.

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

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

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

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

http://www.analog-ni.co/precomposing-a-spa-may-become-the-holy-grail-to-seo

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

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

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

Поддержка поисковой системы для URL-адресов PushState

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 для веб-мастеров в качестве Googlebot. Вы увидите, что ваш JavaScript (включая Angular) выполнен.

Bing

Вот объявление Bing о поддержке довольно PushState URL-адресов от марта 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_ и проиндексирует это.

Pushstate URLs выглядят как обычный URL:

domain.com/path/to/resource

Разница в том, что Angular обрабатывает их для вас, перехватывая изменение document.location, связанное с ним в JavaScript.

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

Тестирование вашего сайта

В Инструментах Google для веб-мастеров теперь есть инструмент, который позволит вам получать URL-адрес в качестве google и отображать JavaScript, как это делает Google.

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

Создание URL PushState в Angular

Чтобы создать реальные URL-адреса в Angular, а не # префиксные, установите режим HTML5 на объект $locationProvider.

$locationProvider.html5Mode(true);

Сторона сервера

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

Карта сайта

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

Хорошая идея иметь карту сайта в любом случае.

Поддержка браузера

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

Демо-страница

Следующий контент отображается с использованием URL-адреса pushstate с предкомпозицией:

http://html5.gingerhost.com/london

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

Обслуживание 404 и 301 Коды состояния заголовка

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

Ответ 3

Давайте окончательно определим AngularJS и SEO

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

Так почему же поисковые системы не занимаются сайтами javascript?

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

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

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

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

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

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

Поисковая система будет искать страницу с помощью

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

Мы можем установить хэш-префикс наших приложений Angular с помощью встроенного метода из 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. Это требует от нас наличия бэкэнд, который поставляет наши страницы с условной логикой посередине. Мы можем использовать что-то вроде бэкэнда prerender.io в качестве отправной точки для запуска этого сами. Конечно, нам все равно нужно обрабатывать проксирование и обработку фрагментов, но это хороший старт.

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

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

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

Ответ 4

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

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

Ответ 6

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

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

Ответ 7

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

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

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

РЕДАКТИРОВАТЬ. Я понимаю, что это может реально испортить ваш REST api, и я не рекомендую делать это за пределами очень простых случаев использования, где это может быть естественным образом.

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

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

Ответ 9

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

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

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

Ответ 10

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

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

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

Ответ 12

Я нашел элегантное решение, которое будет охватывать большинство ваших баз. Я написал об этом вначале здесь и ответил на другой аналогичный вопрос 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' }
   })

metadata-service.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 defined metadata
$rootScope.$on('$routeChangeSuccess', function (event, newRoute) {
  self.loadMetadata(newRoute.metadata);
});

metaproperty.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);
  }
};

index.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), вам все равно придется использовать одну из служб предварительного рендеринга, упомянутых в некоторых других ответах.

Надеюсь, это поможет!

Ответ 13

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

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

Ответ 14

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

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

Ответ 15

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

Ответ 16

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

Мое решение: до дать сканеру то, что хочет искатель:

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

СОВЕТ не путается со спиной. Просто добавьте немного серверного фронтального просмотра, используя тот же API