【问题标题】:Use Backbone Router to deal with Hashbang for SEO content indexing?使用 Backbone Router 处理 Hashbang 进行 SEO 内容索引?
【发布时间】:2014-01-05 14:30:38
【问题描述】:

我的SPA 使用Backbone.js 路由器,它使用pushstate 和散列URL 作为后备方法。我打算使用Google's suggestion for making an AJAX web-app crawlable。也就是说,我想将我的网站索引到由PhantomJS 生成的静态 .html 文件中,并通过 URL 将它们发送给 Google:

mysite.com/?_escaped_fragment_=key=value.

请记住,该网站不为最终用户提供静态页面(它仅适用于支持 Javascript 的浏览器)。如果您导航到mysite.com/some/url.htaccess 文件设置为始终提供mysite.com/index.php,并且主干路由器将读取该 URL,以便显示该 URL 的 JavaScript 生成的内容。

此外,为了让 Google 将我的整个网站编入索引,我计划创建一个 sitemap,这将是 hashbang URLs 的列表。 URL 必须是 hashbanged,以便 Google 知道要使用 _escaped_fragment_key URL 为网站编制索引。

太好了……

(1) 这种方法行得通吗?

(2) 由于backbone.js不使用hashbang URL,当用户使用hashbang URL时如何将hashbang URL转换为pushstate URL 通过 Google 到达?

参考:https://stackoverflow.com/a/6194427/1102215

【问题讨论】:

    标签: javascript ajax backbone.js single-page-application hashbang


    【解决方案1】:

    正如我在问题中概述的那样,我最终在实施过程中磕磕绊绊。所以...

    (1) 是的,这种方法似乎效果很好。唯一的缺点是即使应用程序在没有 hash-bangs 的情况下运行,我的 sitemap.xml 也充满了 hashbang URL。这是必要的,以提醒 Google 在抓取这些页面时应该查询 _escaped_fragment_ URL。因此,当该网站出现在 Google 搜索结果中时,URL 中会出现一个 hashbang,但这是一个很小的代价。

    (2) 这部分比我想象的要容易得多。在初始化 Backbone.js 路由器之前只需要一行代码...

    window.location.hash = window.location.hash.replace(/#!/, '#');
    
    var AppRouter = Backbone.Router.extend({...
    

    hashbang 被替换为仅哈希后,主干路由器将自动删除支持 pushState 的浏览器的哈希。此外,这两个 URL 状态更改保存在浏览器的历史状态中,因此如果用户单击后退按钮,则不会出现异常/意外重定向。

    更新:更好的方法

    事实证明,有一种非常简单的方法可以完全消除 hashbangs。通过BromBone

    如果您的网站使用 hashbangs (#!) 网址,那么 Google 会抓取您的 通过替换#!使用 ?escaped_fragment=。当你看到 ?escaped_fragment=,你会知道这个请求来自一个爬虫。 如果 您正在使用 html5 pushState,然后查看“UserAgent”标头 确定请求是否来自机器人。

    这是 BromBone 建议的 .htaccess 重写规则的修改版本:

        RewriteEngine On
        RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteCond %{HTTP_USER_AGENT} .*Googlebot.* [OR]
        RewriteCond %{HTTP_USER_AGENT} .*Bingbot.* [OR]
        RewriteCond %{HTTP_USER_AGENT} .*Baiduspider.* [OR]
        RewriteCond %{HTTP_USER_AGENT} .*iaskspider.*
        RewriteRule ^(.*)$ snapshot.php/$1 [L]
    

    【讨论】:

    • 快速评论。您不能肯定地说用户代理将在 UA 字符串中包含蜘蛛名称。他们经常将自己伪装成普通浏览器的 UA 字符串,看看会发生什么。这种方法会有所帮助。但是要为您提供“核心”站点内容,您需要将路由发送到服务器,并且在使用 # 时不会将路由发送到服务器。我担心这只会服务于主视图的内容,而不是任何深度链接的内容。这有意义吗?
    • 克里斯,你是在说 RewriteRule 吗?我使用的实际重写规则是RewriteRule ^(.*)$ snapshot.php/$1 [L] ...我已经更新了这个答案以反映这一点
    • 另外,google 不会查找带有 # 的 URL。站点地图中的所有 URL 看起来都像 pushState URL。
    【解决方案2】:

    让我总结一下我在即将出版的关于 SPA 的书中写了大约 10 页的内容。 Google 想要您网站的经典版本。这也是一个优势,因为过时的浏览器无论如何都无法有效地进行 SPA。为蜘蛛和旧浏览器提供核心站点。

    我从 Gaurdian 报纸上得到这个词,http://vimeo.com/channels/smashingconf

    在浏览器中检查浏览器是否切芥末,这是我的脚本:

    <script>
    
        if (!('querySelector' in document)
             || !('localStorage' in window)
             || !('addEventListener' in window)
            || !('matchMedia' in window)) {
    
            if (window.location.href.indexOf("#!") > 0) {
                window.location.href = window.location.href.replace("#!", "?_escaped_fragment_=");
            } else {
                if (window.location.href.indexOf("?_escaped_fragment_=") < 0) {
                    window.location.href = window.location.href + "?_escaped_fragment_=";
                }
            }
    
        } else {
    
            if (window.location.href.indexOf("?_escaped_fragment_=") >= 0) {
                window.location.href = window.location.href.replace("?_escaped_fragment_=", "#!");
            }
        }
    
    </script>
    

    在服务器上,您需要一些机制来检查 _escape_fragment_ 查询字符串是否存在。如果存在,您需要为核心站点提供服务。核心站点仅使用简单的 CSS 和很少或根本没有 JavaScript。我有一个用于 ASP.NET MVC 的 SPAHelper 库,您可以查看我在此方面实现的一些东西,https://github.com/docluv/spahelper

    真正的问题是大多数服务器端 Web 框架(如 ASP.NET、PHP 等)并非旨在支持客户端和服务器的单一视图系统。所以你有点卡住了为此维护两个视图。我再次围绕这个主题为我的书写了大约 10 页,应该在下周的某个时间准备好。

    【讨论】:

    • 克里斯,感谢您的回复。在我的问题中,我写道该网站没有非 JavaScript 版本。 IOW,旧浏览器是 SOL。这是设计使然,因为这是一个基于地图的应用程序。此外,重定向到 escaped_fragment URL 无法达到目的,因为 hashbang URL 在 sitemap.xml 中,因此这些是 Google 将发送给用户的 URL(当网站出现在 Google 的搜索结果中时) )。
    • 如果您阅读 Google 指南,则需要在服务器上生成文档,就像经典网站一样。因此,为什么您使用转义片段查询字符串变量。您必须将核心站点提供给蜘蛛以满足标准。这 #!片段不会被发送到服务器,因此 ?.站点地图应该有 #!版本,蜘蛛知道将该 url 转换为查询字符串版本。
    • 我对你刚才所说的没有异议。我的观点是从 #! 执行 JavaScript 重定向!转义片段 URL 的 URL 是错误的方法。 Google 会在看到 #! 时自动查找 escaped_fragment URL。此外,重定向会将您的用户准确地发送到不应发送到的位置,即:仅用于蜘蛛的静态 html 页面。
    • 不,我认为您没有理解我在说什么。我决定利用搜索引擎需要一个核心站点的优势。因为我需要那个核心站点,所以我将核心站点重新用于服务过时的浏览器。如果访问者使用的是过时的浏览器,那么为他们提供在该浏览器中运行的体验。不要特意创建一个非常复杂的解决方案,让您的现代体验在旧浏览器中运行。要在几年内不应该存在的环境中工作,需要大量的工作和复杂的工作。
    • 好的,我想我明白你在说什么了。语句 if (window.location.href.indexOf("#!") > 0)... 只会针对旧版浏览器进行评估。从你的回答中看不太清楚。如果是这样的话,那么你所做的就很有意义了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-18
    • 1970-01-01
    • 1970-01-01
    • 2016-06-10
    • 2016-04-08
    相关资源
    最近更新 更多