Итак ... Почему потерять полученную информацию плохо? ... потому что автор производного класса, возможно, изменил представление таким образом, что отсечение дополнительной информации изменяет значение, представляемое объектом. Это может произойти, если производный класс, если используется для кэширования представления, более эффективного для определенных операций, но дорогого для преобразования обратно в базовое представление.
Также подумал, что кто-то должен также упомянуть, что вам следует делать, чтобы избежать нарезка ... Получите копию стандартов кодирования C ++, 101 правила и рекомендации.
Он предлагает несколько сложный шаблон, чтобы полностью решить проблему: иметь защищенный экземпляр копии, защищенный чистый виртуальный DoClone и публичный клон с утверждением, которое скажет вам если (далее) производный класс не смог правильно выполнить DoClone. (Метод Clone делает правильную глубокую копию полиморфного объекта.)
Вы также можете пометить конструктор копирования в явном виде базы, который позволяет явно нарезать, если это необходимо.
Google, Yahoo, Bing и другие поисковые системы сканируют сеть традиционными способами с помощью традиционных сканеров. Они запускают роботы , которые сканируют HTML на веб-страницах, собирая информацию на этом пути. Они содержат интересные слова и ищут другие ссылки на другие страницы (эти ссылки, количество их и количество их вступают в игру с SEO).
Ответ на этот вопрос связан с тем, что роботы поисковой системы работают через безгласные браузеры, и они чаще всего выполняют not имеют механизм рендеринга 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
Мы можем установить префикс хеша наших угловых приложений с помощью встроенного метода из 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 backend в качестве отправной точки для запуска этого сами. Конечно, нам все равно нужно обрабатывать проксирование и обработку фрагментов, но это хороший старт.
Самый простой и быстрый способ получить контент в поиске двигатель должен использовать сервис 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 .
Вы должны действительно проверить учебник по созданию SEO-friendly сайта AngularJS в году блога му. Он проведет вас по всем шагам, изложенным в документации Angular. http://www.yearofmoo.com/2012/11/angularjs-and-seo.html
Используя этот метод, поисковая система видит расширенный HTML вместо пользовательского теги.
Я нашел элегантное решение, которое будет охватывать большинство ваших баз. Я написал об этом вначале здесь и ответил на другой аналогичный вопрос StackOverflow здесь , который ссылается на него.
FYI это решение также включает в себя жестко закодированные резервные теги в случае, если Javascript isn «Поднял гусениц. Я не указал его явно, но стоит упомянуть, что вы должны активировать режим 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 (service)
Устанавливает параметры пользовательских метаданных или использует значения по умолчанию в качестве резервных копий.
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), вам все равно придется использовать одну из служб предварительного рендеринга, упомянутых в некоторых других ответах.
Надеюсь, что это помогает!
С помощью функции Angular Universal вы можете создавать целевые страницы для приложения, которые выглядят как полное приложение, а затем загружать приложение Angular. Угловой универсальный генерирует чистый HTML-код, который означает не-javascript-страницы на стороне сервера и обслуживает их без задержки. Таким образом, вы можете иметь дело с любым искателем, ботом и пользователем (у которых уже есть низкая скорость процессора и скорость сети). Затем вы можете перенаправить их по ссылкам / кнопкам на свое фактическое угловое приложение, которое уже загружено за ним. Это решение рекомендуется на официальном сайте. -Подробнее о SEO и Угловом Универсале -
Все изменилось совсем немного, так как этот вопрос был задан. Теперь есть варианты, позволяющие Google индексировать ваш сайт AngularJS. Самый простой вариант, который я нашел, - это использовать бесплатную службу http://prerender.io , которая будет генерировать криволинейные страницы для вас и служить в поисковых системах. Он поддерживается практически на всех серверных веб-платформах. Я недавно начал использовать их, и поддержка тоже прекрасна.
У меня нет никакой связи с ними, это происходит от счастливого пользователя.
Веб-сайт Angular предлагает упрощенный контент для поисковых систем: http://docs.angularjs.org/?_escaped_fragment_=/tutorial/step_09
Скажите, что ваше угловое приложение потребляет Node.js / Экспресс-управляемый JSON api, как /api/path/to/resource
. Возможно, вы можете перенаправить любые запросы с ?_escaped_fragment_
на /api/path/to/resource.html
и использовать согласование содержимого , чтобы отобразить HTML-шаблон содержимого, а не возвращать данные JSON.
Единственное, ваши угловые маршруты должны соответствовать 1: 1 с вашим REST API.
EDIT: Я понимаю, что это может реально испортить ваш REST api, и я не рекомендую делая это за пределами очень простых вариантов использования, где это может быть естественным.
Вместо этого вы можете использовать совершенно другой набор маршрутов и контроллеров для вашего удобного для робота контента. Но затем вы дублируете все свои маршруты и контроллеры AngularJS в узле / Express.
Я решил создать моментальные снимки с безгласным браузером, хотя я чувствую, что это немного меньше, чем идеальный.
Используйте что-то вроде PreRender, оно делает статические страницы вашего сайта, чтобы поисковые системы могли его индексировать.
Здесь вы можете узнать, какие платформы доступны: https: // prerender. И.О. / документация / установка-промежуточные # жерех-сеть
Хорошую практику можно найти здесь:
http://scotch.io/tutorials/javascript/angularjs-seo-with-prerender-io?_escaped_fragment_=tag
Сканерам не нужен богатый признанный стильный gui, они хотят видеть только контент, поэтому вам не нужно давать им снимок страницы, которая была создана для людей.
Мое решение: дать сканеру то, чего хочет искатель:
Вы должны подумать о том, чего хочет искатель, и дать ему только это.
СОВЕТ не путается со спиной , Просто добавьте немного серверного фронтального просмотра, используя тот же API
Google Crawlable Ajax Spec, как указано в других ответах здесь, в основном является ответом.
Если вам интересно, как другие поисковые системы и социальные боты справляются с теми же проблемами, я написал состояние дел здесь: http://blog.ajaxsnapshots.com/2013/11/googles-crawlable-ajax-specification.html
Я работаю для https : //ajaxsnapshots.com , компания, которая реализует Crawlable Ajax Spec как услугу - информация в этом отчете основана на наблюдениях из наших журналов.
Сканеры (или боты) предназначены для сканирования содержимого HTML-страниц на веб-страницах, но из-за операций AJAX для асинхронной выборки данных это стало проблемой, поскольку требуется некоторое время для рендеринга страницы и отображения на ней динамического содержимого. Аналогичным образом, AngularJS
также использует асинхронную модель, что создает проблему для искателей Google.
Некоторые разработчики создают базовые html-страницы с реальными данными и обслуживают эти страницы со стороны сервера во время обхода. Мы можем отображать одни и те же страницы с PhantomJS
на стороне сервиса, которая имеет _escaped_fragment_
(поскольку Google ищет #!
в наших URL-адресах сайта, а затем берет все после #!
и добавляет его в параметр запроса _escaped_fragment_
). Подробнее читайте в этом блоге .
Это радикально изменилось.
Если вы используете: $ locationProvider.html5Mode (true); вы настроены.
Больше страниц рендеринга.
#!
. Из статьи: «Бинг говорит мне, что, хотя они все еще поддерживают #! версия сканируемого AJAX, первоначально запущенная Google, они находят, что она не реализована правильно большую часть времени, и они настоятельно рекомендуют pushState вместо этого. & quot; Вы все равно должны отображать статический HTML и обслуживать его для URL _escaped_fragment_
. Bing / Google не будет выполнять вызовы javascript / AJAX.
– Prerender.io
23 March 2014 в 20:59
_escaped_fragment_
и отображать чистые html-страницы. Это не решает ничего.
– sed
10 September 2014 в 15:46