跳到主要内容

SPA单页应用

单页网页只有一个index.html,页面视图的切换通过JS逻辑实现。在HTML结构中有一个占位DOM元素负责承载切换的视图.可以理解为一个动态显示不同内容的DOM。

SPA的实现基础

  • 保证只有一个HTML页面,且用户交互时不会刷新和跳转页面。为SPA中的每个视图展示形式匹配一个特殊的URL。在浏览器的刷新、前进、回退都通过这个特殊的URL实现。

  • 改变URL且不让浏览器向服务器发送请求。

  • 同时可以监听的URL的变化

如今借助location.hashhistory.pushState可以实现 它们分别对应着如今路由模式中的--Hash模式--和--History模式--

Hash模式

Hash是什么

URL路径中可以存在锚点,通过一个符号 # 表示,当URL存在锚点的时候,锚点后面的字符串在请求时不会传给服务器,仅仅作为本地浏览器数据访问,这个值称为**Hash值**

Hash实现页面跳转

通过 location.hash 可以更改页面的 Hash,并且不会刷新页面、只改变 URL。Hash 改变时触发 hashchange,可据此切换视图。Hash 变化一般也会进入浏览历史,因此可用 history.go() 等控制前进后退。

History模式

History的发展

HTML5前,history只能用于多页面的跳转。 而在HTML5的规范中,history新增了几个API

history.pushState() //添加新的状态到历史状态栈
history.replaceState() //用新的状态代替当前状态
/**
@description: pushState / replaceState 是 History API 方法(不是“pushState 事件”)
@param: state 合法的 JS 对象,可在 popstate 时通过 history.state 取回
@param: title 现在大多数浏览器忽略,可用 null
@param: url 有效 URL,用于更新地址栏
*/

history.state //返回当前的状态

History模式存在的问题

虽然在我们通过history.pushStatehistory.replaceState进行路由跳转更改history.state的时候不会触发页面刷新,但是当用户手动刷新又或者通过URL直接进入应用时,服务端是无法正确识别这个URL,因为在SPA单页应用只有一个index.html,URL地址出现变更在服务器是找不到资源的会出现404,所以需要在服务端进行默认配置,如URL匹配不到任何资源即默认指向单页应用的HTML文件也就是index.html。当然具体怎么设置根据需要进行决策。

两种模式的取舍

flowchart TB
subgraph Hash模式
H1[浏览器访问 /#/about] --> H2[请求仍打到同一 HTML]
H2 --> H3[前端读 hash 渲染]
end
subgraph History模式
Y1[浏览器访问 /about] --> Y2{服务端有该路径资源?}
Y2 -->|无 fallback| Y3[404]
Y2 -->|fallback 到 index.html| Y4[前端读 path 渲染]
end
HashHistory
地址#更接近多页路径
服务端几乎不用特殊配置刷新/直达需 fallback 到 index.html
SEO对传统爬虫不友好URL 更友好,但纯 CSR 本身 SEO 仍然有限,通常还要 SSR/预渲染

总结:不关心 SEO 的后台类应用用 Hash 往往更省心;To C 公网站点更常选 History,并配合 SSR/预渲染与服务端 fallback。

补充

  • Hash模式下,通过hashchange事件监听URL变化,结合DOM操作去更新页面。
  • History模式下,通过popstate事件来捕获URL的变化,并通过pushState去改变当前的URL同时保持页面不刷新。结合DOM操作去更新页面。