历史 PushState API 不支持 url 中的长片段

History PushState API does not support long fragments in the url

目前,我的应用程序在 Backbone.js.

上运行

该应用程序在 # 片段上运行良好,但由于 URL.

中的 # 而无法被 Google 机器人抓取

所以,我决定删除 # 以使其对 SEO 更友好。我启用了 History pushState API 并添加了代码以防止默认操作。这是我初始化路由器实例时的代码片段。

Backbone.history.start({pushState: true});

$(document).on("click", "a", function(e)
        {

            var href = $(e.currentTarget).attr('href');

            var res = Backbone.history.navigate(href,true);
            //if we have an internal route don't call the server
            if(res)
                e.preventDefault();

        });

此外,我修改了我的 Apache 配置以启用 mod_rewrite 以处理无状态请求,例如刷新页面或在新浏览器中打开页面 window。这是我的 Apache 配置片段:

 <IfModule mod_rewrite.c>
            RewriteEngine on
            RewriteRule ^/([a-zA-Z0-9]+)[/]?$ /index.html?pathtyped= [QSA,L]
 </IfModule>

我面临的问题是应用程序可以很好地处理 url 短片段,但不能处理大片段。意思是以下 url 的工作:

http:server_name/#view1 -> http:server_name/view1

http:server_name/#view2 -> http:server_name/view2

http:server_name/#view3 -> http:server_name/view3

但是长片段的url就不行了。 (以下不起作用):

http:server_name/#view1/option1 -> http:server_name/view1/option1

http:server_name/#view2/option1/option2 -> http:server_name/view2/option1/option2

非常感谢任何解决问题的建议。谢谢!

嗯...也许这有帮助(基于 phantomJS):http://traviswimer.com/blog/backbone-seo

我做了一些谷歌搜索,最终偶然发现了 this gist。我用最小的 Backbone.js 应用程序对其进行了测试,它似乎支持无限长的无状态进入应用程序:

<ifModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} !index
    RewriteRule .* index.html [L,QSA]
</ifModule>

我必须阅读一些内容才能完全理解 RewriteCond 语句,特别是 !-f-d!index 在做什么。除了 !index 之外的所有内容都有意义。

试一试,让我知道它是否适合你。

编辑:实际上我发现以上内容仅适用于我 Mac 上的 Homebrew 安装版本的 Apache2,而不适用于 Debian。一些更多的谷歌搜索产生了这种替代形式:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteRule ^index\.html$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.html [L]
</IfModule>

我还整理了一个完整的现代 Backbone.js 应用程序示例,其中包含 pushState 和无状态条目 here

我猜测该应用程序在单个 URL 组件场景中工作,例如 http://server_name/viewX,因为您定义的 Backbone.Router 与 URL 匹配并且成功并使定义为呈现 viewX 的回调(现代浏览器和网络爬虫没有 #,旧浏览器有 #)。因此,当它不起作用时,我会想象定义的路由模式与预期的嵌套 URL 组件不匹配,并且不会触发渲染回调。

您可能会查看 Backbone.Router.routes 散列并确保您的模式在每个深度都与预期的 URL 组件匹配。查看 Backbone documentation on routes,特别是关于可选和嵌套 URL 组件的示例,并检查您的匹配模式是否正确。例如,路由散列包含:

routes: {
    view(/:option1)(/:option2) : renderView
}

应该匹配以 view(或 #view)开头的 URLs,并且可以选择包含一个或两个子参数,例如:

  • view/1
  • view/1/a
  • #view/1
  • #view/1/a

并且在上面的示例中,option1 将被分配 1option2 将被分配 a,并将传递给回调。

路由哈希如下:

routes: {
    view/*option1 : renderView
}

第一个 / 之后的所有内容都将匹配并分配给 option1,例如:

  • view/1/a
  • #view/1/a

在上述两种情况下,option1 将被分配字符串 1/a,并将传递给回调。