年做了大量的 HTML5 项目,遇到了很多坑。在这个过程中学到了一些之前不具备的知识,所以这篇文章就简单分享一下这方面的话题。
传统的MPA
首先,说一个比较古老的东西,叫做 MPA。
MPA 的全称是 Multi-page Application,意思是整个应用(站点)由多个完整的 html 构成。用户在页面 1 点击跳转,需要向服务端请求页面 2,请求成功后渲染。而用户返回时,相当于是点击了浏览器的返回,页面退回到之前的历史记录,并重新加载出来。
在这样的模式下,页面间切换慢、不流畅的问题比较突出,尤其是在移动端。
同时,它还产生了几个小问题:
SPA
随着对移动端体验需求的提高以及技术的进步,另一种模式 SPA(Single-page Application)逐渐成为主流。
SPA 简单来说,就是原来在 MPA 中的多个 html,现在被放在了一个 html 中,并被分成若干个片段。跳转、返回的本质变成了分段的「隐藏」与「显示」。跳转不需要反复对服务端进行请求,从而使得页面与页面之间切换更加快速流畅。
在这样的机制下,跳转与返回完全由代码控制,所以可以通过代码定义页面转场的效果、返回。
在设计转场动画时,我们需要留意的是导航栏是 Native 的还是 HTML5 的。如果导航栏是 Native 的,那 HTML5 页面不包括导航栏,它相当于是网页外的元素,不在转场效果的设计范围内。
WebView
说 HTML5 的跳转,就不得不说 WebView。简单来说,WebView 是在 App 中用于显示 web 内容的容器。上文提到的 MPA 和 SPA,都装在了这个叫做 WebView 的容器中。
用户点击页面中的元素进行跳转,除了前面的两种方式外,还有第三种:新打开 WebView 的方式。在这样的方式下,跳转的本质是 HTML5「告诉」Native,由 Native 执行打开新 WebView,并在新 WebView 中加载页面。
因为 Native 的机制,打开新 WebView 的同时,之前的 WebView 会被自然、完整地保留。所以这时,之前的几个问题就变为:
不过需要注意的地方是,打开新 WebView 是一个资源消耗比较大的操作。如果我们在设计一个流程时,需要比较多的连续使用这种方式,需要和研发同学进行充分的沟通。
比较特殊的Replace
前述的三种跳转,都会产生历史记录。MPA、SPA 的历史记录是在 HTML5 中产生,新开 WebView 中的记录是在 Native 中产生。
在 MPA 或 SPA 中,如果跳转时使用 Replace 方法,它会用新页面替换之前的页面,历史记录中没有之前页面的记录。
这是一种特殊的跳转方式,在设计一些不可逆的流程时可考虑使用。
多页面回退
了解了上述的几种机制后,我们来看一个小的应用场景──多页面回退。
我们在实际业务中,经常会有这样的需求。假设我们有 1、2、3 三个页组成的一个流程,在页面 3 上有个「完成」按钮点击回到页面 1。在不同的交互模式下,实现这样的跳转有着不同的机制。
1. SPA模式下的正常跳转
这种模式是 3 个页面都在一个 WebView 中。点击页面 3 中的「完成」按钮,回退 -2 ,即回退 2 步历史记录,到页面 1。
2. 新打开WebView
打开新 WebView 又分三种方式。
如果我们把 3 个页面,拆分到 2 个 WebView 中,如下图,点击完成按钮,即关闭自身所在的 WebView。
同样是打开新的 WebView,如果我们按如下图的方法拆分会稍微复杂。这时点击完成按钮,首先关闭自身所在的 WebView,当页面 2「意识」到自己重新被展现时,自动退回 1 步到页面 1。
每次打开新的 WebView,这时点击完成,回退的本质是 HTML5「告诉」Native 关闭多个 WebView。需要特别注意的是,HTML5 中实现这种方式不是天然具备的,它需要 Native 具有一次关闭多个 WebView 的能力。所以我们在设计方案时,需要了解清楚自家的 Native 是否有这样的能力。
总结
以上,简单说了几种 HTML5 的跳转方式。这些跳转方式,没有绝对的对与错,我们在设计方案时,需要根据实际的业务需求与技术的限制,来整体考虑解决方案。
根据个人经验,也有几点小帖士分享给大家:
节课来学习超链接实现页面间的跳转。
这是百度的首页,当把鼠标指针滑到百度热搜的文章上,指针形状由箭头变成了小手,点击鼠标左键,会打开一个新的页面,展示这篇热搜文章的内容。
这个功能是如何实现的呢?就是使用超链接。
什么是超链接?当鼠标划入文本时,文字变成蓝色,同时添加了下滑线,这就提示浏览者这不是普通的文本而是可点击的链接。
这个文本被称作 HyperText 意为超文本,这个术语是由泰德-纳尔逊在20世纪60年代提出,是使互联网发挥作用的关键概念之一,超文本是用超链接的方法,将各种不同空间的文字信息组织在一起的网状文本。
超链接就像像桥梁建立了 不同页面之间的联系,实现了访问不同网站中的页面,有了它 就可以在互联网的世界中自由穿梭。
超链接实现通过标准的双标签 a, a 是anchor单词的缩写,是锚的意思,要实现跳转功能必须携带一个属性href ,它是Hypertext Reference 的缩写,意为超文本引用,href的值是目标页面的地址,和图片的 src 属性类似。可以使用相对和绝对路径,标签对内的内容为显示在页面中的文本。
我们来实现一个页面跳转的案例。
打开编辑器,新建文件 anchor.html,向页面中插入两个 a 标签,给每个 a 标签中填入一些显示的文本,千锋教育、千锋前端。
第一个 a 标签定义 href 属性 值为千锋教育的网址(http://www.qfedu.com/) 第二个标签不定义任何属性
在浏览器中打开,两个都表现出来了,可两个标签表现出来的样式明显不同,带有 href 属性的 a 标签文本。 默认样式是蓝色的,并且带有下划线效果。没有 href 属性的 a 标签文本,就没有这些样式了。
鼠标指针划入千锋前端指针的形状仍然是一个小箭头,点击鼠标也没有任何的响应。 鼠标指针划入千锋教育,指针的形状变成了小手,点击鼠标左键的时候。页面跳转到了千锋教育的官网。
需要注意,跳转的目标页面地址,如果是一个网址,需要带上 http://前缀,否则就不能实现页面跳转。
可是当点击超链接的文本时,页面是在原来的窗口中打开的。在点击 百度热搜 的一篇文章上时,会打开一个新的浏览器窗口,页面在新的窗口里显示。
如何实现这个效果?需要给 a 标签添加一个新的属性 target,这个属性的作用是:定义超链接页面打开方式,值定义为 _self,表示链接的目标页面在当前窗口中打开,值定义为 _blank,表示链接的目标页面在新的浏览器窗口中打开。
回到编辑器,给第一个 a 标签添加 target 属性,属性值设置成 _self。回到浏览器,刷新点击千锋教育,仍然在当前窗口中打开,可以看出 _self 就是也是超链接 target 的默认值。
回到编辑器,把 target 的值设置成 _blank,刷新页面,再次点击,页面在新窗口中打开了。
使用超链接跳转页面——完。
文章配套视频链接:
「链接」
黑帽SEO技术不论多么神奇,不管用户看到的页面多么的敏感,但是搜索引擎爬虫看到的永远都是正规的信息,而用户看到的是非常规信息。很明显,这是因为网站页面做了处理,能够分辨出普通用户和搜索引擎,不同的对象调用不同的页面,这个就是网站页面跳转。
什么是网站页面跳转以及为什么要进行页面跳转就不多去细说了,那么怎么进行页面跳转呢。关于网页跳转技术很多,文章也很多,方法代码都很多,但是这些方法差别在那里,那些方法速度更快,那些方法更灵活,那些方法用户能感觉到,为什么能感觉到。夜岛SEO看了一些文章,结合多年的黑帽SEO优化工作经验,通过绘制序列图等办法简单总结一下,换个角度理解一下,希望对大家有所帮助!
本文夜岛重点在于比较http跳转,html跳转,js跳转的工作流程,以及重点分析他们在时间开销上的情况,同时我们重点在于绘制一些图形,然后希望读者能够从图中体会到区别,需要读者体会的地方都用特别区域标识出来了。请大家注意。
网站都是由各种各样页面组成,正常情况下A页面里面包含B页面,C页面的链接,用户在浏览A页面过程中,手工人为点击B链接,然后用户浏览器就显示到B页面。这个过程我们就可以叫页面跳转。
黑帽SEO中常用的站群排名技术99.9%是必须要做跳转的,不然排名上去了给客户看什么内容呢。我们考虑如下场景,一个网站由A,B,C页面构成。正常他们有他们自己显示内容。随着时间推移,发现A页面内容应该同C页面内容相同,但是由于A页面已经被大量用户收藏在浏览器的收藏夹中,或者被搜索引擎收录,若是现在取消A页面的地址(就是取消页面),则对用户是个非常糟糕的事情,但是同时维护两个页面A及C又是个麻烦的事情,稍有疏忽就会造成内容不一致,给用户造成困惑,同时搜索引擎也会不认可。
如何保证A地址不取消,同时又准确保证两个页面显示内容相一致?
我们今天要解决的是在没有用户干预下的页面跳转,完成当用户需要显示页面A时,我们给他显示页面C的内容。
另外为了说明问题方便,我们同时也假设页面B内容也指向内容C,只是采用跳转技术不一样,这样我们方便区别两种行为的差别。
如上图中,展示了用户访问服务器获取页面的一个基本过程。图中主要分为两个部分,左侧区域是用户端,右侧区域是服务端,用户端的用户通过手机或者电脑或者智能设备访问服务端页面。
服务端由若干页面构成,这里简化了服务端行为,并且抽象成三个页面A,B,C,正常情况下服务端应该有很多Action对象,Action对象同页面相对应,提供各种服务,我们仅仅简化Page:A,Page:B,Page:C;
用户端就是手机,包括手机操作操作系统,网络层(tcp/ip/udp等),http等协议层,以及浏览器,浏览器内部进行html的解析,css渲染,js执行引擎等等。
1.用户启动浏览器
2.在浏览器地址中输入域名url地址
3.浏览器发起http请求
4.网络层发起tcp请求到服务器,传输http数据包
5.服务器接收到请求后进行处理,然后返回相关页面内容
6.Tcp接收返回数据给http协议解析系统
7.http将返回数据返回浏览器
8.浏览器解析html数据,处理htmlhead
9.根据head处理后续工作
10.解析body数据
11.处理装载事件Onload(已经开始js的执行,在装入数据过程中已经可以执行一些js事件,具体要根据页面以及浏览器特性而定)
12.根据css进行显示,执行js
13.用户进行后续事情
以上仅仅是典型浏览器行为,具体浏览器行为同页面内容、浏览器特性等都有关系,要具体分析。
根据上面的图1,我们可以有如下分类方法:
一)以跳转地点发生系统那一侧分为:
页面跳转发生在服务端,服务端负责将实际内容获取,然后发送给客户端,这个情况下,一般用户不会感觉到跳转的实际行为,因此有些时候我们也不叫做跳转。具体的服务端跳转行为有很多,各个技术都有各自的特点。例如:Struts2基于注解服务端跳转、<request.getRequestDispatcher(“xx.jsp”).forward(request,response)、<jsp:forwardpage=””/>等,php也有自己的放回,总之各自有各自的办法,夜岛就不一一举例了,大家自己去搜索吧。
跳转行为需要客户单程序参与的一种行为(自然不是用户参与的,那个不是本文讨论的)。在这个过程中,一般用户一定会知道的,浏览器地址栏会发生变化,这个分类比较多,我们专门进行一个分类。
二)用户端跳转中,我们根据跳转行为发生在那个软件层次,分为:http层跳转、应用层跳转;应用层跳转继续分为:htmlhead跳转、js跳转等。
http跳转是指server根据工作情况通过http返回状态码,指示客户端浏览器跳转到相应页面的过程,一般返回码是302.,下面是http302状态码的定义:
Htmlhead头指令跳转
在html代码的head中添加特殊标签,如下
<metahttp-equiv=”refresh”content=”5;url=http://www.heimaoke.com/”/>
表示:5秒之后转到黑帽客网站首页。
这个跳转需要浏览器具体解析html后才能进行,慎重更多时间才能进行,或者情况更复杂。
通过在html代码中添加js代码,通过js代码实现跳转
<scriptlanguage=”javascript”type=”text/javascript”>
window.location.href=”login.jsp?backurl=”+window.location.href;
</script>
这个跳转应该比htmlhead跳转更向后延迟。
页面跳转显示的内容发生在服务端,服务端负责将实际内容获取到,然后发送给客户端。一般用户不会感觉到跳转的实际行为,因此有些时候我们也不叫做跳转
具体工作的参考过程如下:
如上图,用户请求访问PageA,页面A内容指向页面C,相关过程如下:
1.用户通过浏览器访问PageA
2.浏览器通过http处理模块请求GetPageA
3.http处理模块同服务器建立tcp连接,并发出请求获取PageA指令
4.PageA内容指向PageC,通过内部程序将内容C获取到本地
5.PageA接收到PageC的数据后,将数据返回给http模块
6.http模块接收到数据后返回给浏览器
7.浏览器接收到http返回的html数据后,解析html的head
8.处理html的body
9.处理html的onload方法
10.浏览器最后将数据等显示给用户
注意:图中不同斜线的区域
通过server跳转后,用户看到的是PageC的内容,但是浏览器地址栏中地址是PageA的地址。
优点:跳转行为在server进行,一次tcp连接完成相关操作,对用户是透明的,不会造成疑惑。
缺点:对用户隐藏了信息,跳转行为都发生在server端,对server有压力。
server端功能各异,需要分工负责,当用户访问某功能后,需要返回另外一个功能,这个时候没必要把全部功能都放到一个服务器上。
例如:单点登录:用户在某个服务器上登录成功后,一定要在重新跳转到功能服务器上。
网络支付:用户在银行的网站支付完成后,必须重新定向到另外企业应用服务器上。
适用范围:应用内部系统,适当的包含关系时。
http跳转是指server根据工作情况通过http返回状态码,指示客户端浏览器跳转到相应页面的过程,一般返回码是302,下面是http302跳转的相关参考流程
注意图中,区域,颜色,斜线等等。
如上图,用户请求访问PageB,页面B内容指向页面C,相关过程如下:
1.用户通过浏览器访问PageB
2.浏览器通过http处理模块请求GetPageB
3.http处理模块同服务器建立tcp连接,并发出请求获取PageB
4.PageB内容指向PageC,PageB的处理模块通过http的重定向协议通知客户端程序,通过发送消息,302,以及跳到目的地址等进行
5.http处理模块接收到消息后直接跳转到目标地址,同时通知浏览器(修改地址栏)
6.http处理模块请求PageC页面内容
7.PageC处理模块处理数据,生成html代码,返回数据给http处理模块
8.http处理模块接收到数据后放回数据给浏览器
9.浏览器接收到http返回的html数据后,解析html的head
10.处理html的body
11.处理html的onload方法
12.浏览器最后将数据等显示给用户
优点:响应速度快,在http1.1协议下通过合适的设置可以使用同一个tcp连接,节省网络时间,服务器及用户端都不需要进行额外的数据处理工作,节省时间。
缺点:仅仅能做跳转没有其他功能,基于js及html的跳转可以选择延时跳转,但是302无法选择延时跳转等
适用范围:快速跳转,不需要延时,经常用在两个系统之间跳转等。
通过在htmlhead中添加<meta>标签,在标签里指定相关参数,指示浏览器跳转到相应页面,相关跳转必须在http层面将html数据传输给浏览器后,浏览器解释html代码过程中,发现跳转并且根据跳转指令跳转到相应页面。
参考流程如下图:
如上图,用户请求访问PageB,页面B内容指向页面C,相关过程如下:
1.用户通过浏览器访问PageB
2.浏览器通过http处理模块请求GetPageB
3.http处理模块同服务器建立tcp连接并发出请求获取PageB
4.PageB处理模块处理数据,生成html代码,最后将html通过http协议传输回去。
5.http后将数据放回给浏览器,浏览器开始处理html
6.浏览器首先会处理html的head部分,最后发现有跳转的相关指令
7.浏览器根据跳转指令,重新联系http模块,发出获取PageC的指令
8.http通过tcp连接到服务器,获取PageC内容,然后返回给浏览器
9.浏览器接收到http返回的html数据后重新处理html,首先解析html的head
10.处理html的body
11.处理html的onload方法
12.浏览器最后将数据等显示给用户
优点:跳转方式灵活,可以指定延时跳转等等
缺点:可能多次建立tcp连接,在低速网络下效率更低,浪费客户端的时间
最后来看一下js跳转,工作中每个浏览器都有自己的js执行引擎,执行引擎根据js代码,来动态调用浏览器进行跳转,相关参考代码如下:
<scriptlanguage=”javascript”type=”text/javascript”>
window.location.href=”login.jsp?backurl=”+window.location.href;
</script>
具体js跳转过程如下图:
如上图,用户请求访问PageB,页面B内容指向页面C,相关过程如下:
1.用户通过浏览器访问PageB
2.浏览器通过http处理模块请求GetPageB
3.http处理模块同服务器建立tcp连接同server建立连接,并发出请求获取PageB
4.PageB处理模块处理数据,生成html代码,最后将html通过http协议传输回去。
5.http后将数据放回给浏览器,浏览器开始处理html
6.浏览器首先会处理html的head部分,最后会发现有跳转的相关指令
7.浏览器处理html的body,以及js等,最后根据js的指令指示浏览器获取页面C
8.最后根据js的指令指示浏览器获取页面C浏览器会根据跳转指令,重新联系http模块,发出获取PageC的指令
9.http通过tcp连接到服务器,最后获取PageC的内容,然后返回给浏览器
10.浏览器接收到http返回的html数据后重新处理html,首先解析html的head
11.处理html的body
12.处理html的onload方法
13.浏览器最后将数据等显示给用户
优点:跳转方式灵活,可以指定延时跳转等等。
缺点:可能多次建立tcp连接,在低速网络下效率更低,浪费客户端的时间。
使用访问:快速跳转,不需要延时,经常用在两个系统之间跳转等。
当A跳转到B时,我们用符号A–>B表示,下面的循环跳转A–>B–>C–>A,会发生什么事情。若是循环跳转仅仅发生在server端,则相关系统会迅速被拖垮。若是循环跳转发生在客户端参与的系统中,很快客户端及server端都会发生问题。
因此循环跳转我们是要严格避免的,解决办法:
1.不跳转,但是不可能完全避免,并且不太可能实现,一般系统都是开放的系统,会不断添加功能,即使当前没有跳转,但是过几个月。。。。。。
2.打破跳转的循环,加强系统的检查力度避免循环跳转的发生。
3.最重要的,监控系统,当发现某个客户端或者系统在单位时间内有过多的访问时,主动断开连接或者拒绝这个客户端的访问等等。这个非常重要,一个好的系统是必须有这个功能的,否则即使没有循环跳转,但是若是用户连续快速访问一个页面也是有很大问题的,例如ie中按下F5键循环刷新页面,若是没有检测机制。。。。
每种跳转方法对于用户来讲都带来了内容上的变化,原以为A页面的内容变成C页面内容。跳转的方法有很多,夜岛SEO无法为大家一一列举,当我们使用时如何选择那种类别时,需要弄明白每一种跳转的特点,包括:性能,功能等,根据不同网络情况进行不同的选择,例如有的网络建立tcp连接速度慢,这个时候就适宜选择server端的跳转等。
若是保证系统之间的耦合关系更小,系统之间更灵活则需要采用http方式跳转、js跳转,html跳转等。
有的时候需要在跳转前进行一些判断或者额外的操作等,就是js跳转比较方便,但是也有个浏览器适配的问题。有时候一个js兼容性不好的js代码可能不工作,造成部分用户无法跳转。
更多黑帽SEO技术知识学习教程请访问夜岛SEO技术博客(www.yeadao.com),一个专注于黑帽SEO快速排名技术研究与学习教程分享的网站!
*请认真填写需求信息,我们会在24小时内与您取得联系。