在传统的多页面应用中,每个页面都是一个独立的HTML文件,点击链接或进行导航时,浏览器会重新加载整个页面,包括页面的布局、样式和脚本等。这通常需要服务器端处理,并会导致页面的刷新和重新渲染。而在单页面应用中,初始页面的加载只发生一次。通过JavaScript等技术实现动态交互,在用户与应用程序交互时,只更新页面的部分内容,而不用重新加载整个页面。这使得单页面应用更加快速、响应迅速,并提供了更好的用户体验。
单页面应用通常使用前端框架(如React、Angular、Vue等)来管理路由和状态。应用程序的视图被组织成组件,每个组件负责呈现特定的内容。用户与应用程序交互时,通过路由系统切换到相应的组件,并根据需要从后端API获取数据。这些数据更新后,只需要更新相关的组件或部分内容,而不用重新加载整个页面。
可以不刷新网页就改变网页内容,用户体验更好
实现方式分为两种,hash模式和history模式。体现在url上的区别就是是否带有#,#代表是hash模式,没有的话就是history模式。
无论是React还是Vue前端框架渲染时,通常有hash和history两种路由方式。
hash路由模式通过监听url中hash变化渲染不同的内容,它不会向服务器发送请求。
history路由模式是监听url路径变化,需要客户端和服务端支持。
实现原理:
hash是URL中hash(#)及后面的那部分,常用作锚点在页面内进行导航,改变URL中的hash部分不会引起页面刷新。hash路由模式通过监听url中hash变化渲染不同的内容,浏览器不会对#号后面的路径对服务端发起路由请求,也就是说当你请求一个https://juejin.cn/#123和https://juejin.cn/其实到服务端都是去请求https://juejin.cn/这个页面的内容
hash的改变会通过触发hashchange事件监听URL的变化,来渲染对应的页面,通过浏览器前进后退改变URL、通过标签改变URL、通过window.location改变URL,这几种情况改变URL都会触发hashchange事件。
常用API
window.location.hash = '123' // 设置 url 的hash,会在当前url后加上 '#123'
let hash = window.location.hash
console.log(hash) //#123
window.addEventListener('hashchange', function(){
// 监听hash变化
})
实现原理:
history路由模式是监听url路径变化,需要客户端和服务端支持。
history路由会使用到window.history对象的方法,它提供的方法使用操作浏览器的会话历史记录。
back():后退到浏览器会话历史上一次;
forward():前进到浏览器会话历史下一次;
go(number):转到指定某一次浏览器会话历史,正数为前进,负数为后退;
pushState(state,title,url):前进到指定URL,会将URL数据push进会话历史中;
replaceState(state,title,url):将URL替换当前路径;
以上几种方式只会修改当前页面的URL,并不会发送请求。刷新浏览器后,会向服务器发送http网页请求,因此如果使用history路由模式,需要服务端配置。
读到这里可能还是会有疑惑,为什么history需要配置
history路由(不含哈希部分的 URL,基于 HTML5 History API)和哈希路由之间的主要区别在于 URL 结构和浏览器行为。哈希路由之所以不需要额外的服务器配置,是因为它使用 URL 中的哈希部分(#)来管理路由,而这部分不会被发送到服务器。相反,哈希路由只在客户端中进行路由切换,服务器只处理应用的入口点(通常是 index.html)的请求。
普通路由需要额外的服务器配置的原因是:
URL结构:普通路由的 URL 结构是无#的,例如 http://example.com/route。因此,当用户在浏览器中访问这些 URL 时,浏览器会将请求发送到服务器,而不仅仅是在客户端内部进行路由切换。服务器需要知道如何处理这些请求,以便正确返回应用的页面。
页面刷新:当用户刷新包含普通路由的页面时,浏览器将向服务器发送带有特定路由路径的请求。服务器必须能够映射这些请求到应用的入口点,以便前端路由可以重新渲染正确的视图。这需要服务器配置来确保这种映射和处理。
书签和分享链接:普通路由的 URL 更美观和语义化,因此更容易用于书签和分享链接。然而,这也要求服务器能够正确处理这些 URL。
哈希路由避免了上述问题,因为哈希部分不会被发送到服务器,所以服务器不需要特别处理。哈希路由是为了在不进行额外服务器配置的情况下提供前端路由的一种解决方案,特别适用于简单的单页面应用,或者在不需要复杂服务器配置的情况下进行快速开发和原型验证。然而,普通路由通常提供了更美观的 URL,因此在支持现代浏览器的情况下,它可能是更有吸引力的选择。
可以阅读这篇文章路由-前端路由
参考文章
浅谈前端路由
前端开发:带你深入理解路由两种模式
路由-前端路由