在软件开发中,我们时常会说起"前端"和"后端",它们其实并不一定是实际存在的程序实体,而是一种对应用部分的逻辑划分。本文将简要介绍前后端的概念和区分,并讨论一些常见的技术实现方法。
前后端的区分和界限有很多版本,本文主要讨论的是web开发的常见架构,请大佬指教
随着我们的计算机技术进入Web时代,软件所使用的信息通过互联网传输,我们不可避免地遇上一个问题:计算将会在多个设备上运行,我们需要通过合理的信息传递来构建一个功能完备、信息安全的服务。举个例子:在我们网购的时候,我们希望在任何设备上登录电商账号都能查看和管理自己的购物车,又不希望别的用户能够看到我们的购物车。
对于这个问题,我们的前辈们想到了一个显而易见的方案。将一个服务所涉及的计算分割为两个部分:一部分运行在服务提供者的计算机上,用于管理和同步所有的数据,并通过合适的鉴权机制控制这些数据的访问和操作;另一部分运行在服务使用者的计算机上,主要负责显示和渲染用户应该看到的界面,并且处理应用的交互。通常来说,在此处我们将前者称为服务端,后者称为客户端,二者之间通过网络传输必要的数据。在电商购物车的例子中,客户端就是我们手机上的电商应用或者电脑上的电商网页,服务端则是电商公司的服务器(专门用于长期运行互联网服务的电脑)以及服务器上运行的程序。当我们打开购物车页面的时候,我们手中的客户端向服务端发起网络请求,同时传输用户的身份凭证;服务端收到请求后,在服务器上完成身份验证等计算,最终将个人购物车的数据从数据库中取出,通过网络发给客户端。
于是,我们就获得了一个中心化网络下的服务,若干个客户端向同一个服务端发起请求,由这个中心化的服务端向所有的客户端提供数据。在很多情况下,我们将这样的服务端称为后端,将这样的客户端称为前端,这就是最早的前后端划分。让我们归纳一下这样划分的主要内容:
- 服务端(后端):运行在服务器上,中心化,存储和处理数据,校验权限,程序对用户不可见
- 客户端(前端):运行在用户的个人设备上,可以人手一个,渲染和显示用户界面,交互,程序对用户可见
在此处,程序对用户可见是指用户可以获得实际运行的程序的代码(源代码或者机器码)。对于客户端来说,因为需要用户下载、安装并运行,所以程序代码对用户是可见的;服务端的程序代码是由开发者管理的,它运行在服务器上,只是通过网络提供数据接口,因此用户不能获得服务端的程序,也无法直接解析服务端的处理逻辑,从而保证服务的安全性。
然而,动态网页技术的引入和流行,导致了前后端划分的一些变化。关于网页内容的加载和传输过程,请参考我的另一篇文章网页加载过程简述。在动态网页技术(PHP/ASP等)中,服务端实际生成了完整的网页代码,描述了一切与页面有关的内容、样式、交互等,客户端(浏览器)实际只是根据服务端发来的网页代码渲染对应的界面而已,这被称为服务端渲染。在这种情况下,一些开发者认为,前端其实是服务端中负责生成页面代码(内容、样式、交互)的一个部分,前后端都在服务端。在本世纪初期兴起的MVC架构就是这种理论的一个典型实践:在控制器C的调度下,模型M处理与数据库的交互,并将需要的数据传入视图V中生成对应的页面。如此,视图V成为了实际意义的前端,其生成的网页代码被发往客户端,并对用户可见。此时的前后端划分发生了微妙的简化:
- 后端:程序对用户不可见
- 前端:程序对用户可见
这也是我个人比较认可的划分方式。
在HTML5、CSS3、ES等web标准的影响下,浏览器中运行的网页获得了更强的逻辑处理能力,催生了著名的ARV前端框架(Angular/React/Vue)。这些前端框架通过MVVM架构实现了页面的动态渲染和更新,辅以ajax等技术,网页应用可以通过JS代码控制发起请求,从服务端获取数据。我们可以建立一个独立的静态网页,通过JS代码在浏览器中发起网络请求,获得需要的数据后再通过JS控制页面渲染对应的数据。这样的应用被称为单页应用(SPA),这种架构常常被称为前后端分离,因为前端的界面渲染与后端的逻辑没有依赖性,前端程序就像一个"完形填空",从后端获得数据后,将内容(比如用户名、头像、购物车等等)"填入"界面的空白处,实现应用界面的渲染。这样的单页应用可以使用CDN等技术加速载入,同时后端也不需要再处理视图渲染,也更容易实现高并发的服务。
前后端在工程上也有不同的侧重点:
- 前端:主要处理交互,需要美工设计,需要考虑用户体验,争取有更好的细节处理
- 后端:主要处理数据,需要考虑安全和性能,争取有很好的逻辑性和优雅的架构
近些年来Web开发领域也有两个新的趋势。其一是元框架技术(Nextjs,Nuxtjs等)通过混合动态页面和静态页面实现更好的搜索引擎优化。如同服务端渲染时代,这也给前后端的划分带来了一定的混乱。所幸第二个趋势微后端化一定程度上解决了这一点困难:在云计算服务的鼓励下,很多应用选择将尽可能多的计算任务移动到前端,由客户端完成计算。这样做可以节约中心化的服务端的计算压力,同时也可以获得更好的用户体验。举个例子:购物车的总价格,以前往往通过后端完成累加计算,现在往往是前端在获取了购物车列表后现场完成计算,既利用了客户端的计算资源,又能够实时响应购物车列表的变化。其他一些云计算服务,例如Firebase,更是大胆地提出了无后端的概念,通过提供中心化的数据存储来完成数据交换,使用数据读写规则来进行服务的权限控制,将所有的数据处理和服务逻辑都转移到客户端。一些开发者从而认为,处理数据和逻辑的(不是处理界面的)程序部分就是后端,从而导致了前后端都在客户端的情况。我个人是不认可这种划分方式的,我依然认为用户可见的程序(整个静态网页)都是前端。
此外,我还想辨别另外两个词的意思:前台、后台。在一个复杂的应用中,用户往往会被划分为普通用户和管理员。普通用户所使用的程序被称为应用前台;管理员所使用的程序被称为应用后台。举个例子,如果你是电商的顾客,你所看到的购买界面、购物车等等,就是电商应用的前台;如果你是电商的管理员,你所看到的用户管理、数据统计等功能,就是电商的后台。请注意,前后台是根据应用业务划分的,前后端是根据程序架构划分的!时常有非技术人员混用前台/后台/前端/后端,造成很大的困惑。还有一个我个人认为非常不准确的词:中台。在互联网企业中,中台其实是一个商业概念,在技术上表示对现有服务的整合,与本文所讲的前后端、前后台并没有直接关联。我觉得主要是翻译的问题,在这里我把这几个词的英文放在这里,各位自行体会:
- 服务端:server side
- 客户端:client side
- 前端:frontend
- 后端:backend
- 前台:(找不到标准的翻译)user portal/foreground/forestage
- 后台:(找不到标准的翻译)admin portal/background/backstage
- 中台:middle office
看到这个格格不入了吗?希望大家注意区分这几个词汇哦!