它不是在 React JS 的帮助下构建单页应用程序的指南。
这篇文章是关于使现代网络看起来像今天的样子并提供无缝导航体验的工具,使单页应用程序能够存在。
美好的过去
回到过去,互联网及其周围的一切都不同,以及来自网站的期望。一个典型的网站是一组与交叉引用绑定在一起的 HTML 页面。
有时,一些花哨的网站在少数页面上使用 JavaScript,主要用于装饰目的。那里没有发生什么事情,主要是回调地狱。
网络用户体验不是问题,至少没有现在那么大。站点导航非常原始,您单击链接,然后导航到另一个页面。真实的物理页面,即单独存储在服务器上。因此,在向您显示页面之前,浏览器必须请求它并等待它到达。一段时间后,用户会看到所需页面后面的闪烁。
负责为每个请求提供正确页面的模块是服务器路由器。它的配置相当简单。您在服务器上配置路由映射,然后……就是这样,您就完成了。
这是典型的导航流程的样子。
单页应用
从那时起,互联网走了很长一段路。在桌面应用程序和 Web 应用程序之间的持续斗争中,最后一个应用程序在能够提供与其前身相同的外观和感觉之后开始占据主导地位。
现在的现代 Web 应用程序通常会尽量避免中断用户体验并动态替换页面,避免往返服务器的必要性。这种应用程序称为单页应用程序 (SPA)。为了使动态页面替换成为可能,SPA 必须具有某种具有可配置映射的路由器。映射可能是组件的路径、视图的路径、您命名的路径。
为了节省开发的用户体验和本机浏览器行为,客户端路由器必须使用与服务器端路由器相同的事实来源,即 URL 路径。
进化为我们带来了种类繁多的强大框架。大多数可以作为SPA平台。尽管选择了框架,但它肯定会使用两种主要机制之一来实现客户端路由。
哈希路由
首先,最流行的是所谓的 哈希路由。整个方法建立在使用 URL 中的哈希符号之上,特别是利用 JavaScriptwindow.location.hash
属性,该属性返回 URL 中哈希符号之后的所有内容。
后退一步 ,原来的想法 是在 URL 中使用井号,因此window.location
提供了一种锚定到您现在所在页面上某个位置的方法。想象一下,您有一个很大的 HTML 文档,并且您想提供某种目录。添加哈希锚,瞧,现在您可以在页面中导航而无需重新加载它。
很酷的一点是,您可以使用井号共享链接,这样就可以将某人指向您一直在查看的确切段落。正如您此时可能猜到的那样,井号之后的所有内容都被忽略了,并且从未出现在 HTTP 请求中。即使您尝试刷新页面,它也会像往常一样加载,之后您将自动专注于锚定位置。不涉及 javascript,开箱即用。魔法。
正如在 javascript 世界中经常发生的那样,此功能并未按其用途使用。主要框架开始使用它来促进其路由功能。
在进一步的示例中,我将使用 React,但您可以将其替换为您喜欢的任何框架,并且图表不会发生显着变化。
浏览器路由
在 HTML5 发布之前,只有一种以编程方式操作 URL 的方法,也就是我们之前讨论过的一种方法,即通过window.location
属性。HTML5 引入了另一种方法,即 History API。API 的主要目标是提供一个简单的工具来编辑当前会话的浏览器历史记录。看起来这个功能正是路由所需要的,API 有一些功能可以在不触发页面刷新的情况下安全地修改 URL,以及一组用于订阅历史更改的钩子。
这并不完全正确,API 不会修改 URL,它会修改历史记录。将会话历史视为堆栈。一堆 URL,上面的项目是您当前的位置,底部的项目是您访问的第一个网站的 URL。History API 提供了一种将项目推送到堆栈中的方法,它会修改您的当前位置。
如果您现在打开浏览器控制台,粘贴history.pushState(null, null, 'potato');
除 URL 路径之外的任何内容都会更改,更好的是,如果您点击返回按钮,您将回到当前文章的原始路径,无需任何页面刷新。
这给我们带来了另一种路由方式,即在 History API 的帮助下实现的。对于 React,它的名称为 Browser Routing。
这个路由有一个隐藏的怪癖。由于 URL 中不再有“#”符号,一旦用户点击刷新或共享链接,整个 URL 将在 HTTP 请求中传递。服务器将不知道如何处理该路径并返回 404 Not Found HTTP 响应。
现在是考虑期望和责任的好时机。由于我们有一个单页应用程序,我们不希望服务器在路由方面做太多事情。每次请求进入时,只需为我们提供一个页面,通常是 index.html,尽管 URL 路径。一旦加载并准备好滚动,SPA 路由器必须在客户端处理路径本身。
听起来比它更容易。静态网站主机提供商很少允许灵活的路由配置。此外,在实际开发过程中,通常会有某种假服务器参与其中。因此,我们通常会有两个不同的服务器,读取两个不同的问题,幸运的是可以用相同的方法解决。方法是后备策略,必须重新定义。
每次服务器路由器找不到如何解析路径时,它应该回退到初始页面(例如 index.html)并返回它。这样,它将允许客户端路由器处理 URL 路径。
请注意,现在客户端路由器负责处理404 Page Not Found。如果选择的框架未处理它,则可以将 404 页面/组件/任何内容配置为具有满足任何给定路径的路径模式的路由映射中的最后一项。
例子
最流行的虚假开发服务器之一是 webpack dev server。它已经有一个 内置的开关 来管理回退,只需添加一个--history-api-fallback
就可以了。默认情况下,它将回退到 index.html。但是,此属性可作为 devServer webpack 配置的一部分使用,并允许您覆盖默认行为。
现在最流行的静态网站托管之一是AWS S3。它有一个选项来配置他们所谓的错误文档,只需在其中放置一个 index.html 就可以了。
提供的示例并未涵盖所有可能的情况,但应该可以让您了解要查找的内容。
到底
在其他工具和技术中,客户端路由使单页应用程序成为现实。反过来,单页应用程序带来与桌面应用程序相同级别的用户体验。
客户端路由的实现方式有两种主要方法。它们都可以正常工作,但是正如我之前提到的, Hash Routing最初是为不同的目的而构建的。因此,如果您打算使用页面锚定,我建议您切换到Browser Routing。
但是在Browser Routing的情况下,您需要记住页面刷新和共享不会按预期开箱即用,您必须进行一些额外的配置才能使其正常工作。作为Browsing Routing的额外标记,您的 URL 路径看起来会更好。
最后,我建议在可能的情况下使用浏览器路由器。