.htaccess для ботов SEO, сканирующих одностраничные приложения без hashbangs
Используя страницу pushState
enabled, как правило, вы перенаправляете SEO-боты, используя соглашение escaped_fragment
. Вы можете узнать больше об этом здесь.
В соглашении предполагается, что вы будете использовать префикс hashbang (#!
) перед всем вашим URI на одностраничном приложении. SEO-боты будут избегать этих фрагментов, заменив хэш-банд своим собственным узнаваемым соглашением escaped_fragment
при создании запроса страницы.
//Your page
http://example.com/#!home
//Requested by bots as
http://example.com/?_escaped_fragment=home
Это позволяет администратору сайта обнаруживать боты и перенаправлять их на кэшированную предварительно записанную страницу.
RewriteCond %{QUERY_STRING} ^_escaped_fragment_=(.*)$
RewriteRule ^(.*)$ https://s3.amazonaws.com/mybucket/$1 [P,QSA,L]
Проблема заключается в том, что хеш-бэнг быстро прекращается с помощью широко адаптированной поддержки pushState
. Это также очень уродливо и не очень интуитивно понятно для пользователя.
Итак, что, если мы использовали режим HTML5, где pushState направляет все пользовательское приложение?
//Your index is using pushState
http://example.com/
//Your category is using pushState (not a folder)
http://example.com/category
//Your category/subcategory is using pushState
http://example.com/category/subcategory
Можно ли переписать правила для ботов в вашу кеш-версию, используя это новое соглашение? Связанные, но только учетные записи для края индекса. Google также имеет статью, который предлагает использовать метод opt-in для этого случая с одним краем, используя <meta name="fragment" content="!">
в <head>
страницы. Опять же, это для одного края. Здесь мы говорим о том, как обрабатывать каждую страницу в качестве сменного входа.
http://example.com/?escaped_fragment=
http://example.com/category?escaped_fragment=
http://example.com/category/subcategory?escaped_fragment=
Я думаю, что escaped_fragment
все еще можно использовать как идентификатор для ботов SEO, и что я мог бы извлечь все, что находится между доменом и этим идентификатором, чтобы добавить в мое местоположение в ковше, например:
RewriteCond %{QUERY_STRING} ^_escaped_fragment_=$
# (high level example I have no idea how to do this)
# extract "category/subcategory" == $2
# from http://example.com/category/subcategory?escaped_fragment=
RewriteRule ^(.*)$ https://s3.amazonaws.com/mybucket/$2 [P,QSA,L]
Какой лучший способ справиться с этим?
Ответы
Ответ 1
У вас была аналогичная проблема в одностраничном веб-приложении.
Единственное решение, которое я нашел для этой проблемы, - это эффективное создание статических версий страниц с целью создания чего-то навигационного с помощью Google (и других) ботов.
Вы можете сделать это самостоятельно, но есть также службы, которые выполняют именно это, и создают для вас свой статический кеш (и служат для моментальных снимков для ботов по их CDN).
В итоге я использовал SEO4Ajax, хотя доступны другие подобные услуги!
Ответ 2
У меня была такая же проблема. На данный момент я изменил .htaccess следующим образом:
RewriteCond %{QUERY_STRING} ^_escaped_fragment_=(.*)$
RewriteRule ^$ /snapshots/index.html? [L,NC]
RewriteCond %{QUERY_STRING} ^_escaped_fragment_=(.*)$
RewriteRule ^(.*)$ /snapshots/$1.html? [L,NC]
Не уверен, есть ли лучшее решение, но оно работает для меня до сих пор. Просто убедитесь, что структура каталогов для ваших снимков соответствует структуре URL.
Ответ 3
Я использую Symfony2, и хотя мне говорят другие разработчики, что Googlebot и Bingbot работают с Javascript достаточно хорошо, чтобы генерировать собственные HTML-фрагменты, я не уверен в себе. Я также считаю, что обслуживание статических ресурсов - лучшая альтернатива для работы ppl с отключенным JS (хотя это маловероятно), и поэтому я заинтересован в обслуживании HTML-фрагментов в любом случае, если это не хлопот. Ниже приведен метод, который я собираюсь использовать, но не пробовал:
Вот другие вопросы SO, которые похожи (один мой).
Angularjs против SEO против pushState
HTML-фрагменты для приложения AngularJS, использующего pushState?
Вот решение, которое я разместил в этом вопросе и рассматриваю для себя в случае, если я хочу отправить фрагменты HTML в боты. Это было бы решением для бэкэнд Symfony2:
- Используйте prerender или другую службу для создания статических фрагментов всех ваших страниц. Храните их в любом месте, доступном вашему маршрутизатору.
-
В вашем файле маршрутизации Symfony2 создайте маршрут, соответствующий вашему SPA. У меня есть тестовый SPA, работающий на localhost.com/ng-test/, поэтому мой маршрут будет выглядеть следующим образом:
# Adding a trailing / to this route breaks it. Not sure why.
# This is also not formatting correctly in StackOverflow. This is yaml.
NgTestReroute:
----path: /ng-test/{one}/{two}/{three}/{four}
----defaults:
--------_controller: DriverSideSiteBundle:NgTest:ngTestReroute
--------'one': null
--------'two': null
--------'three': null
--------'four': null
----methods: [GET]
-
В вашем контроллере Symfony2 проверьте пользовательский агент, чтобы узнать, является ли он googlebot или bingbot. Вы должны сделать это с помощью кода ниже, а затем использовать этот список для целевых ботов, которые вас интересуют (http://www.searchenginedictionary.com/spider-names.shtml)...
if(strstr(strtolower($_SERVER['HTTP_USER_AGENT']), "googlebot"))
{
// what to do
}
-
Если ваш контроллер обнаружит совпадение с ботом, отправьте ему фрагмент HTML. В противном случае, как и в случае с моим приложением AngularJS, просто отправьте пользователя на индексную страницу, а Angular будет делать все остальное.
Кроме того, если на ваш вопрос был дан ответ, выберите его, чтобы я и другие могли рассказать, что сработало для вас.
Ответ 4
Я использую PhantomJS для создания статических снимков моих страниц. Моя структура каталогов только на одном уровне (root
и /projects
), поэтому у меня есть два файла .htaccess, в которых я перенаправляюсь к файлу PHP (index-bots.php
), который запускает процесс PhantomJS, указанный в моем SPA index.html
и выводит отображаемые статические страницы.
Файлы .htaccess выглядят следующим образом:
/. Htaccess
# redirect search engine bots to index-bots.php
# in order to serve rendered HTML via phantomjs
RewriteCond %{HTTP_USER_AGENT} (bot|crawl|slurp|spider) [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^/index-bots\.php [NC]
RewriteRule ^(.*)$ index-bots.php?url=%{REQUEST_URI} [L,QSA]
/projects/.htaccess
# redirect search engine bots to index-bots.php
# in order to serve rendered HTML via phantomjs
RewriteCond %{HTTP_USER_AGENT} (bot|crawl|slurp|spider) [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ ../index-bots.php?url=%{REQUEST_URI} [L,QSA]
Несколько примечаний:
-
!-f
RewriteCond
имеет решающее значение! Поскольку .htaccess будет применять RewriteRule
ко всем запросам, ресурсы на вашей странице будут переписаны в файл PHP, развернув несколько экземпляров PhantomJS и доведя ваш сервер до колен.
- Также важно освободить
index-bots.php
от перезаписи, чтобы избежать бесконечного цикла.
- Я выделяю JS в своем бегуне PhantomJS script, чтобы гарантировать, что JS ничего не делает, когда боты, которые его поддерживают, сталкиваются с "статическими" страницами.
- Я не мастер .htaccess, поэтому, вероятно, лучший способ сделать это. Я бы хотел услышать это, если да.