参考链接:6 Things You Should Know About Fragment URLs
在项目开发中,因为使用了Vue.js来开发一个SPA(单页面应用),所以在这个项目开始变大的时候,很自然的就想到用vue-router来建立多个模块入口。vue-router默认的是使用hash模式,就是会在#后面跟着路径用来区分并渲染相应的组件,还有一种是history模式,这种模式能在不刷新当前页面的情况下改变URL,并且形式非常干净清爽的,比如:https://segmentfault.com/u/zh...,带上了hash就可能是 https://segmentfault.com#!/u/zhoushx3。
开发过SPA网站的朋友应该知道,SPA是SEO不友好的(后面会解释)。我们一般是会根据URL的路径或者hash来渲染对应的组件或页面。打个比方:
网站首页:aa.bb.com/index
点击页面某一按钮,修改window.location.hash='#how',URL变成aa.bb.com/index#how,同时通过ajax或者其他方式获得数据并渲染。
点击另一按钮,修改window.location.hash='#what',URL变成aa.bb.com/index#what,同时页面更新渲染。
上面我举的栗子是使用hash。当然也可以使用如下的history模式,比如:
网站首页:aa.bb.com/index
点击页面某一按钮,执行history.pushState({}, '', '/how'),URL会变成aa.bb.com/how
点击页面某一按钮,执行history.pushState({}, '', '/what'),URL会变成aa.bb.com/what
使用这种方式URL就会更好看点。
好像有点扯远了,其实我只是想找个引子带出hash这货而已,开始。
认识URL中的Hash
举个栗子:http://www.zuodanye.com/pcent...,代号为W。
对应下URL的组成:protocol :// hostname[:port] / path / ;parameters#fragment
没错,#后面的部分也叫做fragment,带有#的URL也叫Fragment URL。
这里fragment等同于hash.
在#左边的代表这个资源在服务器的位置,右边的则是指明资源内的位置,可以理解成就是锚点。比如标签<a>的用法,<a href='#what'>,当点击它的时候屏幕会滚到它的位置。
Fragment部分没有包含在请求头中
check it out:
据说是因为Fragment部分只对浏览器有用,也就是前端,并且它不会对服务器返回什么资源有所影响,所以这个部分就在Request URL中被忽略掉了。
所以如果把?key=value这部分放在了#后面,那么服务器在拿GET参数的时候就拿不到这块了的哦。
Fragment的特点
修改window.location.hash也就是#后面并不会导致页面刷新,这一点在优化用户体验上是大大的好。
虽然页面不会刷新,不过会在浏览器的history记录中添加一条记录,所以返回和前进按钮就可以利用了。
说说Google爬虫(不同爬虫其原理应该是差不多的)
Google爬虫在爬网站的时候,HTML中的内容和内嵌的链接会成为搜索索引的一部分。由于它并不具有一个脚本引擎,所以它只会爬网站的源码而不会执行任何脚本,这样子#后面的部分就完全失去了作用,毕竟#只有javascrip才会去使用到。
所以,如果使用AJAX和#来区分路径的话,这样的路径是不会被收录到索引的。为了解决这个问题,Google支持了一种转化,即爬虫会把hash部分识别成URL参数,方式:
首先需要把#变成#!,即 http://www.zuodanye.com/pcent... ==> http://www.zuodanye.com/pcenter#!myProject
当Google爬虫遇到这样的URL,会将其识别成 http://www.zuodanye.com/pcent...。
这样子我们只要为这个链接返回相应的页面或者数据即可。
不过这种方式还是显得略不好看,所以如果浏览器支持history API的话,当然还是用history的好。
总结
如果SPA网站要对SEO友好点的话,应该至少有下面的部分:
利用history.pushState来修改URL,监听onpopstate来相应返回和前进。
URL的变化可能如下:www.zuodanye.com -> www.zuodanye.com/pcenter -> www.zuodanye.com/home
这个过程中页面不会刷新,用户体验好。server路由添加/pcenter和/home,以及对应的Render页面,这样子就可以为不同路径下的页面编写不同的TDK。
如果浏览器不支持histroyAPI,那就降级使用hash来切换不同的路径,这样子至少能够不刷新跳转,优化体验。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。