it-swarm.dev

Jak wyszukiwarki radzą sobie z aplikacjami AngularJS?

Widzę dwa problemy z aplikacją AngularJS dotyczące wyszukiwarek i SEO:

1) Co dzieje się z niestandardowymi tagami? Czy wyszukiwarki ignorują całą treść tych tagów? to znaczy załóżmy, że mam

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

czy indeks <h1> zostanie zaindeksowany, mimo że znajduje się w niestandardowych tagach?


2) Czy istnieje sposób na uniknięcie dosłownie wyszukiwarek indeksujących {{}}? to znaczy.

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

Wiem, że mógłbym zrobić coś takiego

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

ale co, jeśli chcę pozwolić robotowi „zobaczyć” tytuł? Czy renderowanie po stronie serwera jest jedynym rozwiązaniem?

695
luisfarzati

Aktualizacja maj 2014

Roboty Google teraz wykonuje javascript - możesz użyć Google Webmaster Tools , aby lepiej zrozumieć, w jaki sposób Twoje witryny są renderowane przez Google.

Oryginalna odpowiedź
Jeśli chcesz zoptymalizować swoją aplikację pod kątem wyszukiwarek, niestety nie ma sposobu, aby udostępnić robotowi wstępnie renderowaną wersję. Możesz przeczytać więcej na temat rekomendacji Google dla stron ajax i ciężkich javascript tutaj .

Jeśli jest to opcja, polecam przeczytanie ten artykuł o tym, jak zrobić SEO dla Angular z renderowaniem po stronie serwera).

Nie jestem pewien, co robi robot, gdy napotka niestandardowe tagi.

404
joakimbl

Użyj PushState i Prekompozycji

Obecnym (2015) sposobem jest skorzystanie z metody pushState JavaScript.

PushState zmienia adres URL na górnym pasku przeglądarki bez ponownego ładowania strony. Załóżmy, że masz stronę z kartami. Zakładki ukrywają i pokazują zawartość, a treść jest wstawiana dynamicznie, używając AJAX lub po prostu ustawiając display: none i display: block, aby ukryć i pokazać poprawną zawartość karty.

Po kliknięciu kart użyj narzędzia pushState, aby zaktualizować adres URL na pasku adresu. Gdy strona jest renderowana, użyj wartości na pasku adresu, aby określić, która karta ma zostać wyświetlona. Angular routing zrobi to za ciebie automatycznie).

Prekompozycja

Istnieją dwa sposoby na uruchomienie aplikacji pojedynczej strony PushState (SPA)

  1. Poprzez PushState, gdzie użytkownik klika link PushState, a zawartość jest AJAXed.
  2. Naciskając bezpośrednio adres URL.

Pierwsze trafienie w witrynie wymaga bezpośredniego trafienia w adres URL. Kolejne działania będą po prostu AJAX w treści, gdy PushState aktualizuje adres URL.

Roboty zbierają linki ze strony, a następnie dodają je do kolejki w celu późniejszego przetworzenia. Oznacza to, że w przypadku przeszukiwacza każde trafienie na serwerze jest trafieniem bezpośrednim, nie nawigują one za pośrednictwem usługi Pushstate.

Prekompozycja łączy początkowy ładunek w pierwszą odpowiedź z serwera, być może jako obiekt JSON. Pozwala to wyszukiwarce na renderowanie strony bez wykonywania wywołania AJAX).

Istnieją pewne dowody sugerujące, że Google może nie wykonać AJAX. Więcej na ten temat tutaj:

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

Wyszukiwarki mogą czytać i uruchamiać JavaScript

Google już od jakiegoś czasu może analizować JavaScript, dlatego pierwotnie opracowali Chrome, aby działał jako w pełni funkcjonalna przeglądarka bezgłowa dla pająka Google. Jeśli link ma prawidłowy atrybut href, nowy adres URL można zindeksować. Nic więcej nie można zrobić.

Jeśli dodatkowo kliknięcie łącza spowoduje wywołanie pushState, użytkownik może nawigować w witrynie za pośrednictwem PushState.

Obsługa wyszukiwarek dla adresów URL PushState

PushState jest obecnie obsługiwany przez Google i Bing.

Google

Oto Matt Cutts odpowiadający na pytanie Paula Irisha dotyczące PushState dla SEO:

http://youtu.be/yiAF9VdvRPw

Oto Google ogłasza pełną obsługę JavaScript dla pająka:

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

Rezultatem jest to, że Google obsługuje PushState i będzie indeksować adresy URL PushState.

Zobacz także pobieranie narzędzi Google dla webmasterów jako Googlebota. Zobaczysz, że JavaScript (w tym Angular) jest wykonywany.

Bing

Oto ogłoszenie Bing dotyczące obsługi ładnych adresów URL PushState z marca 2013 r .:

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

Nie używaj HashBangs #!

Adresy URL Hashbang były brzydką stopą wymagającą od dewelopera dostarczenia wstępnie renderowanej wersji witryny w specjalnej lokalizacji. Nadal działają, ale nie musisz ich używać.

Adresy URL Hashbang wyglądają tak:

domain.com/#!path/to/resource

Zostałoby to sparowane z takim metatagiem:

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

Google nie zaindeksuje ich w tym formularzu, ale zamiast tego pobierze statyczną wersję witryny z adresu URL _escaped_fragments_ i zindeksuje ją.

Adresy URL typu pushstate wyglądają jak każdy zwykły adres URL:

domain.com/path/to/resource

Różnica polega na tym, że Angular obsługuje je za Ciebie, przechwytując zmianę w document.location zajmującą się tym w JavaScript.

Jeśli chcesz używać adresów URL PushState (i prawdopodobnie tak robisz), usuń wszystkie stare adresy URL i metatagi w stylu skrótu i ​​po prostu włącz tryb HTML5 w swoim bloku konfiguracji.

Testowanie witryny

Narzędzia Google dla webmasterów zawierają teraz narzędzie, które pozwala pobrać adres URL jako google i renderować JavaScript podczas renderowania go przez Google.

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

Generowanie adresów URL PushState w Angular

Aby generować prawdziwe adresy URL w Angular, zamiast # z prefiksem, ustaw tryb HTML5 na obiekcie $ locationProvider.

$locationProvider.html5Mode(true);

Po stronie serwera

Ponieważ używasz prawdziwych adresów URL, musisz upewnić się, że ten sam szablon (plus niektóre wstępnie skomponowane treści) zostanie dostarczony przez serwer dla wszystkich prawidłowych adresów URL. To, jak to zrobisz, będzie się różnić w zależności od architektury serwera.

Mapa strony

Twoja aplikacja może korzystać z nietypowych form nawigacji, na przykład najeżdżania myszą lub przewijania. Aby mieć pewność, że Google będzie w stanie prowadzić Twoją aplikację, prawdopodobnie sugerowałbym utworzenie mapy witryny, prostej listy wszystkich adresów URL, na które odpowiada twoja aplikacja. Możesz umieścić to w domyślnej lokalizacji (/ sitemap lub /sitemap.xml) lub poinformować o tym Google za pomocą narzędzi dla webmasterów.

W każdym razie dobrze jest mieć mapę witryny.

Obsługa przeglądarki

Pushstate działa w IE10. W starszych przeglądarkach Angular automatycznie powróci do adresów URL w stylu skrótu

Strona demonstracyjna

Następująca treść jest renderowana przy użyciu adresu URL typu pushstate ze wstępnym składem:

http://html5.gingerhost.com/london

Jak można zweryfikować, w ten link treść jest indeksowana i pojawia się w Google.

Podawanie kodów statusu 404 i 301

Ponieważ wyszukiwarka zawsze trafi na Twój serwer dla każdego żądania, możesz podawać kody statusu nagłówków z serwera i oczekiwać, że Google je zobaczy.

470
superluminary

Uzyskajmy definitywne informacje na temat AngularJS i SEO

Google, Yahoo, Bing i inne wyszukiwarki indeksują sieć w tradycyjny sposób za pomocą tradycyjnych robotów. Działają roboty, które indeksują HTML na stronach internetowych, zbierając po drodze informacje. Zachowują ciekawe słowa i szukają innych linków do innych stron (te linki, ich liczba i liczba wchodzą w grę z SEO).

Dlaczego więc wyszukiwarki nie radzą sobie z witrynami JavaScript?

Odpowiedź ma związek z faktem, że roboty wyszukiwarek działają w przeglądarkach bezgłowych i najczęściej robią nie mają silnik renderujący javascript do renderowania javascript strony. Działa to na większości stron, ponieważ większość stron statycznych nie przejmuje się renderowaniem strony przez JavaScript, ponieważ ich treść jest już dostępna.

Co można z tym zrobić?

Na szczęście roboty w większych witrynach zaczęły wdrażać mechanizm, który pozwala nam na indeksowanie naszych stron JavaScript, ale wymaga to wprowadzenia zmian w naszej witrynie .

Jeśli zmienimy nasz hashPrefix na #! Zamiast po prostu #, Wówczas nowoczesne wyszukiwarki zmienią żądanie użycia _escaped_fragment_ Zamiast #!. (W trybie HTML5, tj. Tam, gdzie mamy linki bez prefiksu skrótu, możemy zaimplementować tę samą funkcję, patrząc na nagłówek User Agent W naszym backendzie).

To znaczy, zamiast żądania z normalnej przeglądarki, która wygląda następująco:

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

Wyszukiwarka przeszuka stronę za pomocą:

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

Możemy ustawić prefiks skrótu dla naszych aplikacji Angular przy użyciu wbudowanej metody z ngRoute:

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

A jeśli używamy html5Mode, Będziemy musieli zaimplementować to za pomocą metatagu:

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

Przypominamy, że możemy ustawić html5Mode() za pomocą usługi $location:

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

Obsługa wyszukiwarki

Mamy wiele możliwości ustalenia, jak poradzimy sobie z faktycznym dostarczaniem treści do wyszukiwarek w postaci statycznego kodu HTML. Możemy sami hostować backend, możemy użyć usługi do hostowania back-endu dla nas, możemy użyć proxy do dostarczenia treści itp. Spójrzmy na kilka opcji:

Hosting własny

Możemy napisać usługę do obsługi przeszukiwania własnej witryny przy użyciu przeglądarki bezgłowej, takiej jak phantomjs lub zombiejs, biorąc migawkę strony z renderowanymi danymi i przechowując ją jako HTML. Ilekroć w zapytaniu wyszukiwania pojawia się ciąg zapytania ?_escaped_fragment_, Możemy dostarczyć statyczną migawkę HTML strony, którą zrobiliśmy, zamiast wstępnie renderowanej strony tylko przez JS. Wymaga to od nas zaplecza, które dostarcza naszym stronom logikę warunkową pośrodku. Możemy użyć czegoś takiego jak prerender.io's backend jako punktu wyjścia do samodzielnego uruchomienia tego. Oczywiście nadal musimy obsługiwać proxy i obsługę fragmentów, ale to dobry początek.

Z płatną usługą

Najłatwiejszym i najszybszym sposobem na pobranie treści do wyszukiwarki jest skorzystanie z usługi Brombone , seo.js , seo4ajax i prerender.io to dobre przykłady tych, które będą hostować powyższe renderowanie treści dla Ciebie. Jest to dobra opcja w czasach, gdy nie chcemy zajmować się uruchomieniem serwera/proxy. Ponadto jest to zwykle bardzo szybkie.

Aby uzyskać więcej informacji na temat Angular i SEO, napisaliśmy obszerny samouczek na ten temat pod adresem http://www.ng-newsletter.com/posts/serious-angular-seo.html i opisaliśmy to jeszcze bardziej w naszej książce ng-book: The Complete Book on AngularJS .Sprawdź to na ng-book.com .

106
auser

Naprawdę powinieneś zapoznać się z samouczkiem na temat budowania przyjaznej SEO witryny AngularJS na blogu moo. Przeprowadzi cię przez wszystkie kroki opisane w dokumentacji Angulara. http://www.yearofmoo.com/2012/11/angularjs-and-seo.html

Korzystając z tej techniki, wyszukiwarka widzi rozszerzony HTML zamiast tagów niestandardowych.

56
Brad Green

To drastycznie się zmieniło.

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

Jeśli użyjesz: $ locationProvider.html5Mode (true); jesteś ustawiony.

Nigdy więcej renderowania stron.

41
user3330270

Od czasu zadania tego pytania wiele się zmieniło. Istnieją teraz opcje umożliwiające Google zaindeksowanie Twojej witryny AngularJS. Najłatwiejszą opcją, jaką znalazłem, było skorzystanie z http://prerender.io bezpłatnej usługi, która wygeneruje dla ciebie strony do crwalable i podajcie to wyszukiwarkom. Jest obsługiwany na prawie wszystkich platformach sieciowych po stronie serwera. Ostatnio zacząłem ich używać, a wsparcie jest również doskonałe.

Nie mam z nimi żadnych powiązań, pochodzi od szczęśliwego użytkownika.

17
Ketan

Własna strona internetowa Angulara udostępnia uproszczoną treść wyszukiwarkom: http://docs.quarejs.org/?_escaped_fragment_=/tutorial/step_09

Powiedz, że Twoja aplikacja Angular używa interfejsu JSON opartego na Node.js/Express, np. /api/path/to/resource. Być może możesz przekierować wszelkie żądania za pomocą ?_escaped_fragment_ do /api/path/to/resource.html i użyj negocjacja zawartości do renderowania szablonu HTML treści, zamiast zwracania danych JSON.

Jedyną rzeczą jest to, że twoje Angular trasy musiałyby być zgodne 1: 1 z twoim REST API).

[~ # ~] edytuj [~ # ~] : Zdaję sobie sprawę, że ma to potencjał, aby naprawdę zabłocić twoje REST api i nie polecam robić tego poza prostymi przypadkami użycia, w których może to być naturalne dopasowanie.

Zamiast tego możesz użyć zupełnie innego zestawu tras i kontrolerów dla treści przyjaznych robotom. Ale następnie powielasz wszystkie swoje trasy i kontrolery AngularJS w Node/Express.

Postawiłem na generowanie migawek za pomocą bezgłowej przeglądarki, mimo że uważam, że to trochę mniej niż idealne.

9
Kevin C.
8
pixparker
7
Thor

Przeszukiwalna specyfikacja Ajax firmy Google, o której mowa w innych odpowiedziach tutaj, jest w zasadzie odpowiedzią.

Jeśli interesuje Cię, w jaki sposób inne wyszukiwarki i boty społecznościowe radzą sobie z tymi samymi problemami, opisałem stan techniki tutaj: http://blog.ajaxsnapshots.com/2013/11/googles-crawlable-ajax -specification.html

Pracuję dla https://ajaxsnapshots.com , firmy, która implementuje specyfikację indeksowania Ajax jako usługę - informacje w tym raporcie oparte są na obserwacjach z naszych dzienników.

6
Robert AJS

Znalazłem eleganckie rozwiązanie, które pokryłoby większość twoich baz. Napisałem o tym początkowo tutaj i odpowiedziałem na inne podobne pytanie StackOverflow tutaj , które go odwołuje.

Do Twojej dyspozycji to rozwiązanie zawiera także zakodowane tagi zastępcze na wypadek, gdyby robot nie wykrył Javascript. Nie określiłem tego wyraźnie, ale warto wspomnieć, że należy aktywować tryb HTML5, aby uzyskać poprawną obsługę adresów URL.

Uwaga: to nie są pełne pliki, tylko ważne części tych, które są istotne. Jeśli potrzebujesz pomocy w napisaniu schematu dla dyrektyw, usług itp., Które można znaleźć gdzie indziej. W każdym razie, oto idzie ...

app.js

Tutaj podajesz niestandardowe metadane dla każdej ze swoich tras (tytuł, opis itp.)

$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 (usługa)

Ustawia niestandardowe opcje metadanych lub używa domyślnych jako rezerwowych.

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

metaproperty.js (dyrektywa)

Pakuje wyniki usługi metadanych dla widoku.

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

W komplecie z wymienionymi wcześniej tagami zastępczymi dla robotów, które nie mogą pobrać żadnego 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>

To powinno radykalnie pomóc w przypadku większości przypadków użycia wyszukiwarek. Jeśli chcesz w pełni dynamicznego renderowania dla przeszukiwaczy sieci społecznościowych (które są luźne w obsłudze Javascript), nadal będziesz musiał skorzystać z jednej z usług wstępnego renderowania wymienionych w niektórych innych odpowiedziach.

Mam nadzieję że to pomoże!

4
Andrew

Za pomocą Angular Universal) możesz wygenerować strony docelowe aplikacji, które wyglądają jak kompletna aplikacja, a następnie załadować swoją Angular aplikacja za nią).
Angular Universal generuje czysty HTML oznacza strony bez javascript po stronie serwera i podaje je użytkownikom bez opóźnień. Dzięki temu możesz poradzić sobie z każdym robotem, botem i użytkownikiem (który ma już niską moc procesora i prędkość sieci). Następnie możesz przekierować je za pomocą linków/przycisków do swojej rzeczywistej angular, która już za nią załadowała) To rozwiązanie jest zalecane przez oficjalną stronę. - Więcej informacji o SEO i Angular Universal -

2
erginduran

Użyj czegoś takiego jak PreRender, tworzy statyczne strony witryny, dzięki czemu wyszukiwarki mogą je indeksować.

Tutaj możesz dowiedzieć się, jakie platformy są dostępne: https://prerender.io/documentation/install-middleware#asp-net

2
NicoJuicy

Przeszukiwacze (lub boty) są zaprojektowane do przeszukiwania treści HTML stron internetowych, ale z powodu AJAX operacje asynchronicznego pobierania danych), stało się to problemem, ponieważ wyświetlenie strony i wyświetlenie na niej dynamicznej treści zajmuje trochę czasu. Podobnie, AngularJS używa również modelu asynchronicznego, który stwarza problem dla robotów Google.

Niektórzy programiści tworzą podstawowe strony HTML z prawdziwymi danymi i obsługują te strony od strony serwera podczas indeksowania. Możemy renderować te same strony z PhantomJS po stronie wyświetlania, która ma _escaped_fragment_ (Ponieważ Google szuka #! w adresach URL naszej witryny, a następnie bierze wszystko po #! i dodaje go w _escaped_fragment_ parametr zapytania). Aby uzyskać więcej informacji, przeczytaj to blog .

1
Rubi saini

Przeszukiwacze nie potrzebują bogatego, ładnie zaprojektowanego GUI, chcą tylko zobaczyć treść, więc nie musisz im przedstawiać migawki strony stworzonej dla ludzi.

Moje rozwiązanie: do podaj robotowi to, czego chce robot:

Musisz pomyśleć o tym, czego chce robot i dać mu tylko to.

WSKAZÓWKA nie zadzieraj z plecami. Wystarczy dodać mały widok z przodu serwera przy użyciu tego samego interfejsu API

0
pykiss