SPA之SEO

金旋
• 阅读 8982

参考链接: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来渲染对应的组件或页面。打个比方:

  1. 网站首页:aa.bb.com/index

  2. 点击页面某一按钮,修改window.location.hash='#how',URL变成aa.bb.com/index#how,同时通过ajax或者其他方式获得数据并渲染。

  3. 点击另一按钮,修改window.location.hash='#what',URL变成aa.bb.com/index#what,同时页面更新渲染。

上面我举的栗子是使用hash。当然也可以使用如下的history模式,比如:

  1. 网站首页:aa.bb.com/index

  2. 点击页面某一按钮,执行history.pushState({}, '', '/how'),URL会变成aa.bb.com/how

  3. 点击页面某一按钮,执行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:
SPA之SEO

据说是因为Fragment部分只对浏览器有用,也就是前端,并且它不会对服务器返回什么资源有所影响,所以这个部分就在Request URL中被忽略掉了。
所以如果把?key=value这部分放在了#后面,那么服务器在拿GET参数的时候就拿不到这块了的哦。

Fragment的特点

修改window.location.hash也就是#后面并不会导致页面刷新,这一点在优化用户体验上是大大的好。
虽然页面不会刷新,不过会在浏览器的history记录中添加一条记录,所以返回和前进按钮就可以利用了。

说说Google爬虫(不同爬虫其原理应该是差不多的)

Google爬虫在爬网站的时候,HTML中的内容和内嵌的链接会成为搜索索引的一部分。由于它并不具有一个脚本引擎,所以它只会爬网站的源码而不会执行任何脚本,这样子#后面的部分就完全失去了作用,毕竟#只有javascrip才会去使用到。
所以,如果使用AJAX和#来区分路径的话,这样的路径是不会被收录到索引的。为了解决这个问题,Google支持了一种转化,即爬虫会把hash部分识别成URL参数,方式:

不过这种方式还是显得略不好看,所以如果浏览器支持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来切换不同的路径,这样子至少能够不刷新跳转,优化体验。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
Java获得今日零时零分零秒的时间(Date型)
publicDatezeroTime()throwsParseException{    DatetimenewDate();    SimpleDateFormatsimpnewSimpleDateFormat("yyyyMMdd00:00:00");    SimpleDateFormatsimp2newS
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
Java日期时间API系列36
  十二时辰,古代劳动人民把一昼夜划分成十二个时段,每一个时段叫一个时辰。二十四小时和十二时辰对照表:时辰时间24时制子时深夜11:00凌晨01:0023:0001:00丑时上午01:00上午03:0001:0003:00寅时上午03:00上午0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
1年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
美凌格栋栋酱 美凌格栋栋酱
5个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
金旋
金旋
Lv1
我还是很喜欢你,只是少了当初非在一起的理由。
文章
3
粉丝
0
获赞
0