【问题标题】:.htaccess for SEO bots crawling single page applications without hashbangs.htaccess 用于 SEO 机器人在没有 hashbang 的情况下抓取单页应用程序
【发布时间】:2013-07-29 08:55:25
【问题描述】:

使用启用pushState 的页面,通常您使用escaped_fragment 约定重定向搜索引擎优化机器人。您可以阅读更多关于 here 的信息。

约定假定您将在单个页面应用程序上的所有 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]

问题在于 hashbang 正在被广泛采用的 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

是否可以使用此更新的约定重写规则将机器人引导到您的缓存版本? Related but only accounts for index edge case. Google 还 has an article 建议在页面的 <head> 中使用 <meta name="fragment" content="!"> 对这种单一边缘情况使用 opt-in 方法。同样,这是针对单个边缘情况。在这里,我们正在讨论将每个页面作为 opt-in 场景来处理。

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]

处理此问题的最佳方法是什么?

【问题讨论】:

  • 嗨@dan-kanze ..我有同样的问题..你有什么解决方案或任何可以帮助我的东西吗..我坚持这个
  • 我去过那里,pushState 似乎要求您将这些文件夹放在您的光盘上。这样,那些不支持 pushState 的人将能够看到该页面以及机器人。

标签: javascript .htaccess web-crawler single-page-application


【解决方案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 sn-ps,但我并不自信。我也觉得提供静态资源是关闭 JS 运行 ppl 的更好选择(尽管不太可能),所以无论如何我对提供 HTML sn-ps 感兴趣,只要它不麻烦。以下是我正在考虑使用但尚未尝试过的方法:

      这里有其他类似的 SO 问题(一个是我的)。
      Angularjs vs SEO vs pushState
      HTML snippets for AngularJS app that uses pushState?

      这是我在该问题中发布的一个解决方案,我正在考虑自己以防万一我想将 HTML sn-ps 发送给机器人。这将是 Symfony2 后端的解决方案:

      1. 使用 prerender 或其他服务生成所有页面的静态 sn-ps。将它们存储在路由器可以访问的地方。
      2. 在您的 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]

      3. 在您的 Symfony2 控制器中,检查用户代理以查看它是 googlebot 还是 bingbot。您应该可以使用下面的代码执行此操作,然后使用此列表定位您感兴趣的机器人 (http://www.searchenginedictionary.com/spider-names.shtml)...

        if(strstr(strtolower($_SERVER['HTTP_USER_AGENT']), "googlebot"))
        {
        // what to do
        }

      4. 如果您的控制器找到与机器人匹配的内容,请将 HTML sn-p 发送给它。否则,就像我的 AngularJS 应用一样,只需将用户发送到索引页面,Angular 就会正确地完成剩下的工作。

      另外,如果您的问题已得到解答,请选择一个,以便我和其他人知道什么对您有用。

      【讨论】:

        【解决方案4】:

        我正在使用 PhantomJS 生成页面的静态快照。我的目录结构只有一层(root/projects),所以我有两个 .htaccess 文件,我在其中重定向到一个 PHP 文件(index-bots.php),该文件启动一个指向我的 SPA @987654324 的 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 会将RewriteRules 应用于所有请求,因此您页面上的每个资产都将被重写为 PHP 文件,从而启动多个 PhantomJS 实例并使您的服务器瘫痪。
        • 避免index-bots.php 进行重写以避免死循环也很重要。
        • 我在我的 PhantomJS 运行脚本中删除了 JS,以确保当支持它的机器人遇到“静态”页面时 JS 不会做任何事情。
        • 我不是 .htaccess 向导,所以可能有更好的方法来做到这一点。如果是这样,我很乐意听到。

        【讨论】:

          猜你喜欢
          • 2014-05-30
          • 2013-08-11
          • 2023-03-15
          • 1970-01-01
          • 2014-05-11
          • 2011-01-13
          • 2018-09-02
          • 1970-01-01
          • 2019-08-13
          相关资源
          最近更新 更多