【问题标题】:History PushState API does not support long fragments in the urlHistory PushState API 不支持 url 中的长片段
【发布时间】:2018-01-26 22:21:59
【问题描述】:

目前,我的应用程序在 Backbone.js 上运行。

该应用程序与 # 片段一起正常工作,但由于 URL 中的 #,它无法被 Google 机器人抓取。

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

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 以处理无状态请求,例如刷新页面或将页面打开到新的浏览器窗口。这是我的 Apache 配置 sn-p:

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

我面临的问题是应用程序可以很好地处理短 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

但是带有长片段的网址不起作用。 (以下不起作用):

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

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

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

【问题讨论】:

    标签: javascript html backbone.js pushstate


    【解决方案1】:

    我做了一些谷歌搜索,最终偶然发现了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

    【讨论】:

    • 我实际上发现上面的方法在我的 Mac 上有效,但在 Linux 主机上无效,所以我做了一些谷歌搜索并找到了另一种形式。完整的例子在这里github.com/amoeba/backbone-pushstate-example。编辑我的帖子以显示这一点。
    【解决方案2】:

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

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

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

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

    • 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,并将被传递给回调。

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-10-19
        • 2012-10-29
        • 2013-01-26
        • 1970-01-01
        • 2011-04-30
        • 2011-06-04
        • 1970-01-01
        • 2011-09-12
        相关资源
        最近更新 更多