使用REACT、REDUX和SSR在没有JavaScript的情况下控制用户

2020-06-07 12:21:26

一些东西是否可以在没有JavaScript(JS)的情况下工作,这是黑客新闻评论中时不时会出现的问题--大多数时候是不能的。

这些有JS残疾的人是谁,为什么没有它事情就不能正常运作?前者当然是少数,但即便如此,随着NoScript成为下载量排名第七的Firefox插件和其他浏览器,以及现有的禁用JS的方式,这些用户也不容忽视。对于后者-我不知道。也许现代网络开发人员很懒。也许他们工作过度了,预算太低,时间紧迫。也许支持noscript太难了。也许他们甚至不知道JS可以被禁用,也不知道为什么有人会这样做。

我并不声称有这些问题的答案,但是有一段时间我已经有了一个想法,那就是如何以一种不会给开发人员带来太大负担的方式容纳这些用户。以下是实现此目的的一种方法的简短探索,并提供了一个展示该方法的演示。这是我希望在将来的某个时候实现我的愿望礼物,我的副业,但更重要的是,我希望有人能想出更好的东西。

说JS被大量使用是温和的说法,所有网站中有95.8%的网站在客户端使用它。我相信很多这样的网站在没有JS的情况下都能正常工作,这很棒。另一方面,肯定有一些没有JavaScript就不能工作的Web应用,比如WebGL/Canvas体验、音频编辑器、游戏面板测试,以及严重依赖浏览器中的JSAPI的其他Web应用。介于这两个之间的某个地方,您会发现CRUD应用程序(复杂程度各不相同)在没有JS的情况下不能工作,或者只能部分工作。

每个Web应用程序的一个基本组件是呈现HTML,这通常会反映一些状态。像Reaction这样的框架在现代Web开发中经常被用来帮助渲染和交互性。这些框架中的许多都有处理状态的方法,并且许多框架还允许将状态存储在其他地方,比如Redux-“用于JS应用程序的可预测状态容器”,它采用了事件源模式。

像Redux这样的基于事件的状态容器非常适合我们的目的,因为它与一种可以在浏览器中使用和不使用JS表单提交的交互完美地结合在一起!放到redux存储中的所有东西都应该是可序列化的,我们在表单中提交的任何东西都应该是可序列化的-至少对于enctype=";application/x-www-form-urlencoded";.是这样的。虽然对于是否应该将所有的状态都放到Redux中没有“正确”的答案,但是如果我们这样做了-当然可能会有更多的工作-我们得到了一个可以同时运行客户端和服务器端的集中式存储。

然后,该存储可以充当呈现的HTML所反映的状态的基准或单一真值来源。考虑到Reaction(和其他)框架支持服务器端呈现,我们可以在一些聪明、有远见和谨慎的情况下创建一个单独的Reaction应用程序,在使用和不使用JS的情况下都可以使用(使用大量加载)。

首先,我们创建帮助器组件,这些组件将抽象出拥有和不拥有JS之间的主要区别。要实现经典的TodoMVC应用程序,我只需要Button和Form组件,第一个组件是“Do this on click”的包装器,后者是依赖于用户更多输入的更通用的操作包装器。这两个帮助器的工作原理相同,即将包含整个操作(类型和有效负载)的表单呈现为表单元素。当Reaction应用程序在客户端运行时,将阻止提交事件,并将操作分派到客户端。如果没有JS,则不会阻止事件,并且会在我们当前所处的任何路由上向服务器发出请求。

在服务器端,除了监听视图路由上的GET请求外,我们还监听POST请求。对于所有GET请求,我们将返回初始的Reaction应用程序,该应用程序将为任何使用JS的用户恢复消重数据。我们对任何POST请求都是这样做的,但我们也假设,任何人向这些路由发出POST请求的唯一原因是因为他们提交了一个表单。有了这个假设,我们将检查请求中是否确实存在包含类型的主体,并且可能还包含有效负载和有效负载类型。如果我们发现了这一点,我们将检查当前会话上是否有某种状态,并使用该状态初始化Redux存储。然后,我们将提交的操作分派到存储区,获取结果状态,更新会话状态,并使用存储区呈现我们的应用程序。

您可以在这里查看实现所有这些的演示,并在这里查看源代码。

我们不能访问正在提交的任何仅限JS事件的表单,这意味着没有必要进行任何必要的交互,比如拖动、双击、长时间单击等。

我们得到了一些额外的标记,我们在设计样式时必须考虑这些标记,因为所有东西都必须包装在表单中-我们不能使用带有onclick处理程序的独立按钮。

服务器端会话管理可能会以比演示中更好的方式来完成,而在生产中,您可能需要对提交的操作进行更多的清理和验证。

如果使用这种方法实现Web应用,没有JS的用户将会有源源不断的更新,但在许多情况下,另一种选择是根本没有Web应用。

这当然可以使用Reaction和Redux之外的其他框架来实现。也许这甚至可能是Sapper或Next.js中可以找到出路的东西呢?

简而言之,通过利用表单事件和Redux等基于事件的状态容器的相似性,我们可以通过使所有操作都通过表单来为未启用JS的用户分派和更新服务器端的状态。通过使用一些帮助器组件来捕获、阻止和分派客户端的事件,这会变得更容易,而且几乎不需要做任何重复的工作就能获得好处。对于最基本的功能,我们可以使用什么样的交互是有限的,并且不得不在样式、安全性和服务器成本方面采取一些额外的预防措施,但这可能比没有JS的用户根本不能使用应用程序更好。

感谢您阅读这篇文章!我也很想听听你的想法和想法。加入黑客新闻的讨论,或者随时给我发电子邮件给我,地址是这个博客所在的域的Daniel。