검색 엔진은 AngularJS 애플리케이션을 어떻게 처리합니까?


697

검색 엔진 및 SEO와 관련된 AngularJS 응용 프로그램에는 두 가지 문제가 있습니다.

1) 맞춤 태그는 어떻게 되나요? 검색 엔진은 해당 태그 내의 전체 내용을 무시합니까? 즉 내가 가지고 있다고 가정

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

것이 <h1>내부의 사용자 정의 태그를 임에도 불구하고 색인?


2) 색인 생성 {{}} 검색 엔진이 문자 그대로 바인딩되는 것을 피할 수있는 방법이 있습니까? 즉

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

나는 내가 할 수있는 일을 알고있다

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

그러나 실제로 크롤러가 제목을 "보도록"하려면 어떻게해야합니까? 서버 측 렌더링이 유일한 솔루션입니까?


17
이 모든 "솔루션"은 적어도 Google 등이 더 지능적인 크롤러를 가질 때까지 AngularJS와 같은 기술을 피하고 싶습니다.
Codemonkey

22
@Codemonkey : 네, 구글 제품인 AngularJS가 왜 이것에 대한 빌트인 솔루션을 제공하지 않았는지 궁금 할 것입니다. 실제로 Wierd ..
Roy MJ

11
실제로 Misko는 Google에서 일하기 전에 Angular를 썼습니다. Google은 이제이 프로젝트를 후원하지만 창시자는 아닙니다.
superluminary

2
아마도 여기에있는 누군가가 SPA의 Wikipedia 기사를 업데이트하거나 업데이트해야 할 수도 있습니다. "SPA는 일반적으로 검색 엔진 인덱싱이 필요하거나 바람직한 컨텍스트에서 사용되지 않습니다." en.wikipedia.org/wiki/Single-page_application [# 검색 엔진 최적화] IsNat이라는 (불분명 한) 자바 기반 프레임 워크에 대해서는 큰 단락이 있지만 Angularjs와 같은 SEO에 의해 해결되었다는 제안은 없습니다.
linojon

3
@Roy MJ-왜 아무도 의도를 보지 못합니까? PageSpeed, Angular 등은 SERP에서 자연스럽고 유기적 인 목록의 모든 적입니다. 의도적으로 클릭당 지불을 기반으로 한 거대한 비즈니스 모델이있는 경우 옵션을 제공하지 않는 전체 도구 상자를 만드는 것보다 사람들이 목록에 대한 비용을 지불하도록하는 것이 더 나은 방법은 무엇입니까? 귀중한 컨텐츠로 가득 찬 양질의 웹 사이트를 구축하는 대신,이 산업에는 스쿼트를 달성하거나 해결하지 못하는 치트와 솔루션이 넘쳐납니다.
Steven Ventimiglia

답변:


403

2014 년 5 월 업데이트

Google 크롤러는 이제 자바 스크립트를 실행 합니다. Google 웹 마스터 도구 를 사용하여 Google에서 사이트를 렌더링하는 방법을 더 잘 이해할 수 있습니다.

원래 답변
검색 엔진에 맞게 앱을 최적화하려는 경우 불행히도 사전 렌더링 된 버전을 크롤러에 제공 할 방법이 없습니다. 아약스 및 자바 스크립트가 많은 사이트에 대한 Google의 권장 사항에 대한 자세한 내용은 여기를 참조하십시오 .

이것이 옵션이라면 서버 측 렌더링으로 Angular를 위해 SEO를 수행하는 방법에 대한 이 기사 를 읽는 것이 좋습니다 .

맞춤 태그를 발견했을 때 크롤러의 기능을 잘 모르겠습니다.


13
더 이상 최신 상태가 아닙니다. 이제 pushState를 대신 사용해야합니다. 별도의 정적 버전 사이트를 제공 할 필요가 없습니다.
superluminary April

3
내가 Google 웹 마스터 도구에서 볼 수 있듯이, 심지어 구글 업데이트,보기 겨 것은, 제대로 렌더링되지 않습니다
tschiela

10
예, 자바 스크립트를 실행한다고해서 페이지가 올바르게 색인 생성되는 것은 아닙니다. 가장 안전한 방법은 Google bot useragent를 감지하고 phantomjs와 같은 헤드리스 브라우저를 사용하며 page.content정적 HTML을 가져 오고 반환하는 것입니다.
테스터

6
이 질문은 SEO에만 해당된다는 것을 알고 있지만 다른 크롤러 (Facebook, Twitter 등)는 아직 JavaScript를 평가할 수 없습니다. 예를 들어, 소셜 미디어 사이트에서 페이지를 공유하는 것은 여전히 ​​서버 측 렌더링 전략 없이는 문제가 될 수 있습니다.
Stephen Watkins

3
누군가 Google 크롤링 스키마 사양을 구현하지 않고 AngularJS 사이트의 색인을 올바르게 생성 할 수 있습니까?
check_ca

470

PushState 및 사전 구성 사용

이를 수행하는 현재 (2015) 방법은 JavaScript pushState 메소드를 사용하는 것입니다.

PushState는 페이지를 다시로드하지 않고 상단 브라우저 표시 줄의 URL을 변경합니다. 탭이 포함 된 페이지가 있다고 가정하십시오. 탭은 컨텐츠를 숨기고 표시하며 AJAX를 사용하거나 단순히 display : none 및 display : block을 설정하여 올바른 탭 컨텐츠를 숨기고 표시하여 컨텐츠를 동적으로 삽입합니다.

탭을 클릭하면 pushState를 사용하여 주소 표시 줄에서 URL을 업데이트하십시오. 페이지가 렌더링 될 때 주소 표시 줄의 값을 사용하여 표시 할 탭을 결정하십시오. 각도 라우팅은 자동으로이를 수행합니다.

사전 조성

PushState 단일 페이지 앱 (SPA)을 누르는 방법에는 두 가지가 있습니다.

  1. PushState를 통해 사용자가 PushState 링크를 클릭하면 컨텐츠가 AJAX됩니다.
  2. URL을 직접 누르십시오.

사이트의 초기 조회에는 URL을 직접 누르는 것이 포함됩니다. PushState가 URL을 업데이트함에 따라 후속 조회는 단순히 콘텐츠의 AJAX입니다.

크롤러는 페이지에서 링크를 수집 한 후 나중에 처리 할 수 ​​있도록 대기열에 추가합니다. 이는 크롤러의 경우 서버의 모든 조회가 직접 조회이며 Pushstate를 통해 이동하지 않음을 의미합니다.

사전 구성은 초기 페이로드를 서버의 첫 번째 응답 (가능한 경우 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를 읽고 실행할 수 있습니다

구글은 한동안 자바 스크립트를 파싱 할 수 있었기 때문에 구글 스파이더의 완전한 기능을 갖춘 헤드리스 브라우저 역할을하기 위해 원래 크롬을 개발했다. 링크에 유효한 href 속성이 있으면 새 URL을 색인화 할 수 있습니다. 더 이상 할 일이 없습니다.

링크를 클릭하면 pushState 호출이 트리거되면 사용자가 PushState를 통해 사이트를 탐색 할 수 있습니다.

PushState URL에 대한 검색 엔진 지원

PushState는 현재 Google 및 Bing에서 지원됩니다.

구글

SEO에 대한 PushState에 대한 Paul Irish의 질문에 응답하는 Matt Cutts가 있습니다.

http://youtu.be/yiAF9VdvRPw

스파이더에 대한 완전한 JavaScript 지원을 발표 한 Google은 다음과 같습니다.

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

결론은 Google이 PushState를 지원하고 PushState URL을 색인화한다는 것입니다.

Google 웹 마스터 도구의 Googlebot으로 가져 오기도 참조하십시오. JavaScript (Angular 포함)가 실행되는 것을 볼 수 있습니다.

다음은 2013 년 3 월자 예쁜 PushState URL 지원에 대한 Bing의 발표입니다.

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

HashBangs #을 사용하지 마십시오!

Hashbang URL은 개발자가 특별한 위치에 사전 렌더링 된 버전의 사이트를 제공해야하는 추악한 스탑 갭입니다. 그들은 여전히 ​​작동하지만 사용할 필요는 없습니다.

해시 방 URL은 다음과 같습니다.

domain.com/#!path/to/resource

이것은 다음과 같은 메타 태그와 쌍을 이룰 것입니다 :

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

Google은이 형식으로 색인을 생성하지 않지만 대신 _escaped_fragments_ URL에서 정적 버전의 사이트를 가져와 색인을 생성합니다.

푸시 스테이트 URL은 일반 URL과 같습니다.

domain.com/path/to/resource

차이점은 Angular는 JavaScript에서 처리하는 document.location의 변경 사항을 가로 채어 처리합니다.

PushState URL을 사용하고 싶을 경우 모든 이전 해시 스타일 URL과 메타 태그를 꺼내고 구성 블록에서 HTML5 모드를 활성화하면됩니다.

사이트 테스트

Google 웹 마스터 도구에는 이제 URL을 Google로 가져오고 Google이 렌더링하는대로 JavaScript를 렌더링 할 수있는 도구가 포함되어 있습니다.

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

각도로 PushState URL 생성

접두사 # 개가 아닌 Angular로 실제 URL을 생성하려면 $ locationProvider 객체에서 HTML5 모드를 설정하십시오.

$locationProvider.html5Mode(true);

서버 측

실제 URL을 사용하고 있으므로 유효한 모든 URL에 대해 동일한 템플릿 (일부 사전 구성 컨텐츠)이 서버에서 제공되도록해야합니다. 이를 수행하는 방법은 서버 아키텍처에 따라 다릅니다.

사이트 맵

앱에서 호버 또는 스크롤과 같은 비정상적인 탐색 형식을 사용할 수 있습니다. Google이 앱을 구동 할 수 있도록 앱이 응답하는 모든 URL의 간단한 목록 인 사이트 맵을 만드는 것이 좋습니다. 기본 위치 (/ sitemap 또는 /sitemap.xml)에 배치하거나 웹 마스터 도구를 사용하여 Google에 알려줄 수 있습니다.

어쨌든 사이트 맵을 갖는 것이 좋습니다.

브라우저 지원

Pushstate는 IE10에서 작동합니다. 구형 브라우저에서는 Angular가 자동으로 해시 스타일 URL로 대체됩니다.

데모 페이지

다음 컨텐츠는 사전 구성이 포함 된 pushstate URL을 사용하여 렌더링됩니다.

http://html5.gingerhost.com/london

확인할 수 있듯이이 링크 에서 콘텐츠가 색인되어 Google에 표시됩니다.

404 및 301 헤더 상태 코드 제공

검색 엔진은 모든 요청에 ​​대해 항상 서버에 도달하므로 서버에서 헤더 상태 코드를 제공하고 Google에서이를 확인할 수 있습니다.


설명을 해 주셔서 감사합니다. 내가 궁금해하는 한 가지는 Google이 페이지를 색인 생성하기 전에 자바 스크립트를 실행합니까?
jvv

1
"PushState는 페이지를 다시로드하지 않고 상단 브라우저 표시 줄의 URL을 변경합니다 ... 탭을 클릭 할 때 pushState를 사용하여 주소 표시 줄의 URL을 업데이트하십시오. 페이지가 렌더링 될 때 주소 표시 줄의 값을 사용하여 각진 라우팅이 자동으로이를 수행합니다. " 전구!
atconway

1
@superluminary, 주제를 좀 더 깊이 설명해 주시겠습니까? 특히 '서버 측'섹션. angularjs + angularjs-route + locationProvider.html5Mode + api + 동적 탐색을 사용하고 있습니다 (html5.gingerhost.com과 같은 정적 브라우저는 아닙니다. URL은 잘 표시되지만 내용은 색인화되지 않은 것 같습니다. 직접 URL로 페이지에 액세스하는 동안 어떻게 든 정적 콘텐츠를 제공합니까? 실제로 다음과 같은 메시지가 표시됩니다. >> 모든 유효한 URL에 대해 동일한 템플릿을 서버에서 제공해야합니다. 사전.
Sray

1
@sray-사이트의 모든 URL이 동일한 템플릿을 제공하는 경우 브라우저는 템플릿을 가져올 수 있으며 Angular는 URL을 검사하고 올바른 내용을 렌더링하여 템플릿을 가져올 수 있습니다. 서버에서 해당 URL을 직접 누르면 404 또는 500을 반환하면 문제가 발생하고 직접 링크가 작동하지 않고 책갈피가 작동하지 않고 색인이 생성되지 않는 것입니다. 이제 보입니까?
superluminary

1
@ user3339411-사이트가 응답 할 모든 페이지마다 하나의 URL이 있어야합니다. 사이트가 하나의 컨텐츠 세트로 하나의 URL에만 응답해야하는 경우 라우팅이 전혀 필요하지 않습니다. 간단한 사이트에는 좋습니다. 그러나 사이트에서 다른 URL에 대해 다른 데이터 (JSON을 통해)를 가져 오는 경우 라우팅을 사용하는 것이 좋습니다. Github 정적 페이지는 파일 기반이므로이 인스턴스의 각 URL을 뒷받침하는 실제 html 파일이 필요합니다. 그러나 웹 사이트가 파일 기반이어야한다는 규칙은 없으며 대체 플랫폼을 사용하는 경우 여러 URL에 대해 동일한 템플릿을 제공 할 수 있습니다.
superluminary

107

AngularJS와 SEO에 대해 결정합시다

Google, Yahoo, Bing 및 기타 검색 엔진은 기존 크롤러를 사용하여 기존 방식으로 웹을 크롤링합니다. 웹 페이지에서 HTML을 크롤링하여 정보를 수집 하는 로봇 을 실행 합니다. 그들은 흥미로운 단어를 유지하고 다른 페이지에 대한 다른 링크를 찾습니다 (이러한 링크, 그 수 및 SEO와 관련된 수).

그렇다면 검색 엔진이 자바 스크립트 사이트를 다루지 않는 이유는 무엇입니까?

답은 검색 엔진 로봇이 헤드리스 브라우저를 통해 작동 하며 페이지의 자바 스크립트를 렌더링하는 자바 스크립트 렌더링 엔진 이 없는 경우와 관련 있습니다. 대부분의 정적 페이지는 컨텐츠가 이미 사용 가능하므로 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 태그를 사용하여이를 구현해야합니다.

<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 , seo4ajaxprerender.io 서비스를 사용하는 것입니다. 위의 콘텐츠 렌더링을 호스팅하는 좋은 예입니다. 서버 / 프록시 실행을 다루고 싶지 않을 때 좋은 옵션입니다. 또한 일반적으로 매우 빠릅니다.

각도 및 검색 엔진 최적화에 대한 자세한 내용은, 우리는 그것을에 광범위한 자습서를 썼다 http://www.ng-newsletter.com/posts/serious-angular-seo.html 하고 우리는 더욱 우리의 책에서 그것을 설명 NG 책 : AngularJS에 대한 완전한 책 . ng-book.com 에서 확인하십시오 .


1
SEO4Ajax 는 유료 서비스의 좋은 예입니다 (베타 기간 동안 무료). 불행히도,이 응답을 편집하여 목록에 추가 할 수없는 것 같습니다.
check_ca

1
@auser 여전히이 방법을 권장합니까? 새로운 최고 투표 의견은이 접근법을 권장하지 않는 것 같습니다.
리차

이것은 CS에서 "definitive guide"와 같은 것을 말해서는 안되는 이유에 대한 훌륭한 예입니다. :) 주요 검색 엔진은 이제 Javascript를 실행하므로이 답변은 모두 다시 작성하거나 삭제해야합니다.
Seb

1
@seb 로봇이 크롤링 할 때 페이지에 있어야하는 오픈 그래프 태그를 가정 해 봅시다. 예를 들어 Facebook 또는 Twitter 카드에 필요합니다. 그러나이 답변은 현재 사용되지 않는 hashbang 대신 HTML5 푸시 상태에 초점을 맞추도록 업데이트해야합니다.
adriendenat

@Grsmto 당신이 맞아요! 그런 다음 주요 검색 엔진이 JS를 실행하지 않는다고 말했기 때문에 다시 작성해야한다고 생각합니다. 더 이상 사실이 아닙니다.
Seb

57

moo 블로그 연도에 SEO 친화적 인 AngularJS 사이트를 구축하는 방법에 대한 자습서를 확인하십시오. 그는 Angular의 문서에 요약 된 모든 단계를 안내합니다. http://www.yearofmoo.com/2012/11/angularjs-and-seo.html

이 기술을 사용하면 검색 엔진은 맞춤 태그 대신 확장 된 HTML을 봅니다.


@ 브래드 그린 (Brad Green)조차도 질문이 종결되었으므로 (어떤 이유로 든) 당신이 대답 할 수있는 위치가 될 수 있습니다. 내가 뭔가
Christoph

41

이것은 크게 바뀌었다.

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

사용하는 경우 : $ locationProvider.html5Mode (true); 당신은 설정됩니다.

더 이상 렌더링 페이지가 없습니다.


3
이것은 지금 최고 답변이어야합니다. 우리는 2014 년에 @joakimbl의 답변이 더 이상 최적이 아닙니다.
Stan

11
이것은 올바르지 않습니다. 이 기사 (2013 년 3 월부터)는 Bing이 자바 스크립트를 실행하는 것에 대해 아무 말도하지 않습니다. Bing은 단순히 이전 권장 사용 대신 pushstate 사용을 권장합니다 #!. "Bing은 Google에서 처음 시작한 #! 버전의 크롤링 가능한 AJAX를 계속 지원하면서도 제대로 구현되지 않았으며 대신 pushState를 권장한다고 말합니다." 여전히 정적 HTML을 렌더링하여 _escaped_fragment_URL에 제공해야 합니다. Bing / Google은 javascript / AJAX 호출을 실행하지 않습니다.
Prerender.io

2
여전히 _escaped_fragment_순수한 HTML 페이지 가 필요 하고 렌더링됩니다. 이것은 친구를 해결하지 않습니다.
Stan

여전히 Google 로봇은 내 사이트의 동적 콘텐츠를 볼 수없고 빈 페이지 만 볼 수 있습니다.
calmbird

검색 사이트 : mysite.com은 AngularJS를 통해로드 된 컨텐츠가 아닌 {{staff}}를 보여줍니다. Google 크롤러가 JavaScript에 대해 들어 본 적이없는 것처럼. 어떡해?
툴킷

17

이 질문을 한 이후에는 상황이 약간 바뀌 었습니다. Google이 AngularJS 사이트를 색인 할 수있는 옵션이 있습니다. 내가 찾은 가장 쉬운 옵션은 http://prerender.io 무료 서비스 를 사용 하여 크롤링 가능한 페이지를 생성하고 검색 엔진에 제공하는 것입니다. 거의 모든 서버 측 웹 플랫폼에서 지원됩니다. 나는 최근에 그것들을 사용하기 시작했으며 지원도 훌륭합니다.

나는 그들과 아무런 관계가 없습니다. 이것은 행복한 사용자로부터 온 것입니다.


6
prerender.io의 코드는 github ( github.com/collectiveip/prerender )에 있으므로 누구나 자체 서버에서 실행할 수 있습니다.
user276648

이것은 이제 구식입니다. 아래 @ user3330270의 답변을 참조하십시오.
Les Hazlewood

2
이것은 구식이 아닙니다. @ user3330270의 답변이 잘못되었습니다. 그들이 링크하는 기사는 단순히 #! 대신 pushstate를 사용한다고 말합니다. 크롤러는 자바 스크립트를 실행하지 않기 때문에 여전히 크롤러에 대한 정적 페이지를 렌더링해야합니다.
Prerender.io

9

Angular의 자체 웹 사이트는 검색 엔진에 단순화 된 컨텐츠를 제공합니다. http://docs.angularjs.org/?_escaped_fragment_=/tutorial/step_09

Angular 앱이 Node.js / Express-driven JSON api를 소비한다고 가정 해보십시오 /api/path/to/resource. 아마도 당신은 어떤 요청을 리디렉션 수 ?_escaped_fragment_/api/path/to/resource.html, 및 사용 내용 협상을 내용의 HTML 템플릿, 오히려 수익보다 JSON 데이터를 렌더링 할 수 있습니다.

유일한 것은 Angular 경로가 REST API와 1 : 1과 일치해야한다는 것입니다.

편집하다 : 나는 이것이 REST API를 실제로 어지럽 힐 가능성이 있음을 알고 있으며 자연스럽게 맞을 수있는 매우 간단한 유스 케이스 이외의 작업은 권장하지 않습니다.

대신 로봇 친화적 인 컨텐츠에 대해 완전히 다른 경로 및 컨트롤러 세트를 사용할 수 있습니다. 그러나 Node / Express에서 모든 AngularJS 경로와 컨트롤러를 복제합니다.

헤드리스 브라우저로 스냅 샷 생성을 결정했습니다. 비록 그것이 다소 이상적이지 않다고 생각합니다.



7

현재 Google은 AJAX 크롤링 제안을 변경했습니다.

시간이 변경되었습니다. 현재 Googlebot이 JavaScript 또는 CSS 파일을 크롤링하는 것을 차단하지 않는 한 일반적으로 최신 브라우저와 같은 웹 페이지를 렌더링하고 이해할 수 있습니다.

tl; dr : [Google]은 더 이상 2009 년에 작성된 AJAX 크롤링 제안 [Google]을 권장하지 않습니다.


@Toolkit 무슨 뜻인가요?
Thor

1
Googlebot은 Angular 웹 사이트를 구문 분석 할 수 없습니다
Toolkit

4
@Toolkit 당신이 절대 후프를 얘기하는 것은, 내 전체 각도 사이트는 문제없이 동적 메타 데이터와 구글에 의해 색인하고있다
트위그

@ twigg 당신은 잘못된 논리를 가지고 있습니다. 하나의 Angular 웹 사이트가 색인화되었다는 것을 의미합니다. 글쎄, 나는 당신에게 놀람이 있습니다. 내 인덱스는 없습니다. 내가 각도 UI 라우터를 사용하거나 이유를 알고 있기 때문일 수 있습니다. 아약스 데이터가없는 메인 페이지조차도
Toolkit

@Toolkit 정적 HTML 페이지조차 색인화되지 않은 경우 Google의 JS 파일 크롤링 기능과 관련이 없습니다. 구글이 제대로 크롤링 할 수 없다고 말하는 경우 .. 글쎄, 난 당신이 틀렸다고 생각한다
phil294

6

여기의 다른 답변에서 참조 된 Google의 Crawlable Ajax Spec은 기본적으로 답변입니다.

다른 검색 엔진 및 소셜 봇이 최신 기술을 작성한 것과 동일한 문제를 처리하는 방법에 관심이있는 경우 http://blog.ajaxsnapshots.com/2013/11/googles-crawlable-ajax-specification.html

크롤러 블 Ajax 사양을 서비스로 구현하는 회사 인 https://ajaxsnapshots.com 에서 일하고 있습니다.이 보고서의 정보는 로그의 관찰을 기반으로합니다.


링크는 나열된 blog.ajaxsnapshots.com에 있습니다
Kevin

4

나는 당신의 기지 대부분을 덮을 우아한 해결책을 찾았습니다. 나는 처음에 여기에 썼고 여기 에 또 다른 비슷한 StackOverflow 질문에 대답 했습니다. 있는 참조를.

참고 로이 솔루션에는 크롤러가 Javascript를 선택하지 않은 경우 하드 코딩 된 대체 태그도 포함됩니다. 명시 적으로 설명하지는 않았지만 적절한 URL 지원을 위해 HTML5 모드를 활성화해야한다고 언급 할 가치가 있습니다.

참고 : 이들은 완전한 파일이 아니며 관련 파일의 중요한 부분 일뿐입니다. 다른 곳에서 찾을 수있는 지시문, 서비스 등을위한 상용구 작성에 도움이 필요한 경우. 어쨌든, 여기 간다 ...

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's 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를 지원하는 소셜 네트워크 크롤러에 대해 완전한 동적 렌더링을 원한다면 다른 답변 중 일부에서 언급 한 사전 렌더링 서비스 중 하나를 사용해야합니다.

도움이 되었기를 바랍니다!


나는 또한이 솔루션을 따르고 있으며 이전에는 그렇게 생각했지만 검색 엔진이 사용자 정의 태그의 내용을 읽도록 요청하고 싶습니다.
Ravinder Payal



2

Angular Universal을 사용하면 완전한 앱처럼 보이는 앱의 랜딩 페이지를 생성 한 다음 Angular 앱을 그 뒤에로드 할 수 있습니다.
Angular Universal은 서버 측에서 자바 스크립트가없는 페이지를 의미하는 순수한 HTML을 생성하여 지연없이 사용자에게 제공합니다. 따라서 크롤러, 봇 및 사용자 (이미 CPU 및 네트워크 속도가 낮은)를 처리 할 수 ​​있습니다. 그런 다음 링크 / 버튼을 사용하여 이미로드 된 실제 각도 앱으로 링크 / 버튼을 리디렉션 할 수 있습니다. 이 솔루션은 공식 사이트에서 권장합니다. SEO 및 Angular Universal에 대한 자세한 정보


1

크롤러 (또는 봇)는 웹 페이지의 HTML 컨텐츠를 크롤링하도록 설계되었지만 비동기 데이터 페치에 대한 AJAX 조작으로 인해 페이지를 렌더링하고 동적 컨텐츠를 표시하는 데 시간이 걸리므로 문제가되었습니다. 마찬가지로 AngularJS비동기 모델을 사용하면 Google 크롤러에 문제가 발생합니다.

일부 개발자는 실제 데이터가 포함 된 기본 HTML 페이지를 만들고 크롤링 할 때 서버 쪽에서이 페이지를 제공합니다. 우리와 같은 페이지를 렌더링 할 수 PhantomJS있다 측의 역할에 _escaped_fragment_(구글을 찾습니다 때문에 #!우리의 사이트 URL에을하고 이후 모든 필요 #!하고 그것을 추가 _escaped_fragment_쿼리 매개 변수). 자세한 내용은이 블로그 를 참조하십시오 .


2017 년 10 월 현재이 소득세 계산기는 더 이상 유효하지 않습니다.이 소득세 계산기 수입 -tax.co.uk 는 순수한 AngularJ로 빌드됩니다. 월급 </ title>은 '세금 £ 30000에 대한 세금 계산기'와 같이 렌더링되며 Google은 색인을 생성하여 수백 개의 키워드에 대해 첫 페이지에 순위를 매 깁니다. 인간을 위해 웹 사이트를 구축하고 멋지게 만드십시오. Google은 나머지를 처리합니다. ;)
Kaszoni Ferencz

0

크롤러는 풍부한 기능을 갖춘 예쁜 스타일의 GUI 가 필요하지 않으며 콘텐츠 만보 고 싶어 하므로 사람을 위해 만들어진 페이지의 스냅 샷을 제공 할 필요가 없습니다.

내 솔루션 : 크롤러가 원하는 것을 크롤러에게 제공 .

크롤러가 원하는 것을 생각하고 그에게만 주어야합니다.

팁은 뒤를 엉망으로하지 않습니다. 동일한 API를 사용하여 서버 측 프론트 뷰를 추가하기 만하면됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.