历史 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
将被分配 1
,option2
将被分配 a
,并将传递给回调。
路由哈希如下:
routes: {
view/*option1 : renderView
}
第一个 /
之后的所有内容都将匹配并分配给 option1
,例如:
view/1/a
#view/1/a
在上述两种情况下,option1
将被分配字符串 1/a
,并将传递给回调。
目前,我的应用程序在 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
将被分配 1
,option2
将被分配 a
,并将传递给回调。
路由哈希如下:
routes: {
view/*option1 : renderView
}
第一个 /
之后的所有内容都将匹配并分配给 option1
,例如:
view/1/a
#view/1/a
在上述两种情况下,option1
将被分配字符串 1/a
,并将传递给回调。