.htaccess用于SEO机器人在没有哈希标签的情况下抓取单页应用程序
.htaccess for SEO bots crawling single page applications without hashbangs
使用启用了pushState
的页面,通常使用escaped_fragment
约定重定向SEO机器人程序。您可以在此处阅读更多有关的信息。
该约定假设您将在单个页面应用程序上的所有URI之前使用(#!
)hashbang前缀。SEO机器人在发出页面请求时,会将hashbang替换为自己可识别的约定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
支持,hashbang正在迅速被淘汰。它也很难看,对用户来说不是很直观。
那么,如果我们使用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
可以使用这个新的约定重写规则,将机器人引导到您的缓存版本吗?相关但仅说明索引边缘情况。谷歌也有一篇文章,建议在页面的<head>
中使用<meta name="fragment" content="!">
,对这种单边缘情况使用opt-in方法。同样,这是针对单个边缘的情况。在这里,我们讨论的是作为选择加入senario来处理每个页面。
http://example.com/?escaped_fragment=
http://example.com/category?escaped_fragment=
http://example.com/category/subcategory?escaped_fragment=
我认为escaped_fragment
仍然可以用作SEO机器人的标识符,并且我可以提取域和该标识符之间的所有内容,以附加到我的bucket位置,如:
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]
处理这个问题的最佳方法是什么?
在单页web应用程序上也遇到了类似的问题。
我发现这个问题的唯一解决方案是有效地创建页面的静态版本,以便让谷歌(和其他)机器人可以导航。
你可以自己做,但也有一些服务可以做到这一点,并为你创建静态缓存(并通过CDN向机器人提供快照)。
我最终使用了SEO4Ajax,尽管还有其他类似的服务!
我也遇到了同样的问题。目前,我已经修改了.htaccess,如下所示:
RewriteCond %{QUERY_STRING} ^_escaped_fragment_=(.*)$
RewriteRule ^$ /snapshots/index.html? [L,NC]
RewriteCond %{QUERY_STRING} ^_escaped_fragment_=(.*)$
RewriteRule ^(.*)$ /snapshots/$1.html? [L,NC]
不确定是否有更好的解决方案,但到目前为止,它对我有效只要确保快照的目录结构与URL结构匹配即可
我正在使用Symfony2,尽管其他开发人员告诉我,Googlebot和Bingbot执行Javascript的能力足以生成自己的HTML片段,但我并不自信。我还觉得,对于关闭JS运行的ppl来说,提供静态资源是一个更好的选择(尽管这不太可能),所以我对提供HTML片段很感兴趣,只要这不是一件麻烦的事。以下是我正在考虑使用但尚未尝试的方法:
以下是其他类似的SO问题(其中一个是我的)。
Angularjs vs SEO vs pushState
使用pushState的AngularJS应用程序的HTML片段?
这是我在这个问题上发布的一个解决方案,我正在考虑自己,以防我想把HTML片段发送给机器人。这将是Symfony2后端:的解决方案
- 使用prerender或其他服务生成所有页面的静态片段。将它们存储在路由器可以访问的地方
-
在Symfony2路由文件中,创建一条与SPA匹配的路由。我在localhost.com/ng-test/上运行了一个测试SPA,所以我的路线看起来是这样的:
# 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控制器中,检查用户代理,看看它是谷歌机器人还是bingbot。你应该能够用下面的代码做到这一点,然后使用这个列表来瞄准你感兴趣的机器人(http://www.searchenginedictionary.com/spider-names.shtml)。。。
if(strstr(strtolower($_SERVER['HTTP_USER_AGENT']), "googlebot"))
{
// what to do
}
-
如果您的控制器找到与机器人程序匹配的内容,请将HTML片段发送给它。否则,就像我的AngularJS应用程序一样,只需将用户发送到索引页面,Angular就会正确地完成其余操作
此外,如果你的问题得到了回答,请选择一个,这样我和其他人就可以告诉你什么对你有效。
我使用PhantomJS生成页面的静态快照。我的目录结构只有一级深(root
和/projects
),所以我有两个.htaccess文件,在其中我重定向到一个PHP文件(index-bots.php
),该文件启动指向我的SPA index.html
的PhantomJS进程,并打印出渲染的静态页面。
.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
s,因此页面上的每个资产都将被重写到PHP文件中,从而启动PhantomJS的多个实例,并使服务器瘫痪- 同样重要的是要免除
index-bots.php
的重写,以避免无休止的循环 - 我在PhantomJS runner脚本中去掉了JS,以确保当支持JS的机器人遇到"静态"页面时,JS不会做任何事情
- 我不是.htaccess向导,所以可能有更好的方法。如果是的话,我很想听
- 第二组标签及其内容赢得'默认情况下t加载
- 如何使html链接标签可以在没有标签的情况下工作
- 如何在不使用像素的情况下使这些标签大小相同
- 如何在不输出结束PHP标签“?>”的情况下将PHP MySQL查询回显到Javascript变量中
- 如何在没有代码隐藏访问权限的情况下将自定义 HTML 属性添加到 ASP.NET 标签
- 在不刷新的情况下更新标签内的变量
- 谷歌地图与方向 - 我可以在没有表单标签的情况下做到这一点吗?
- AngularJS:在不修改ng模型的情况下获取选择标签
- jQuery.text() - 如何在不影响任何子元素的情况下更改标签的文本
- 如何在没有 AngularJs 编码的情况下在图像“alt”标签中使用字符串
- 如何在不使用选框标签的情况下滚动图像?Javascript,jquery或css任何东西
- 如何更新p的标签:在primefaces中ajax调用后,在不关闭组件的情况下选择CheckboxMenu
- 在这种特殊情况下,如何使用Jquery获取标签的文本
- .htaccess用于SEO机器人在没有哈希标签的情况下抓取单页应用程序
- 在不回发的情况下动态更新母版页标头中的标签或文本框
- 如何在不干扰标签内输入无线电的情况下更改标签文本?
- 在没有JQuery的情况下搜索DOM查找特殊的html标签
- 如何在没有内容的情况下为单个标签着色?
- 如何在没有自定义HTML标签的情况下使用AngularJS
- 如何在不使用iframe和标签的情况下显示弹出式联系表单