手记

投稿004期 | 剖析WEB前后端技术的原理和实现

前言

使用浏览器访问网站是日常生活中必不可少的一件事情,当我们在浏览器地址栏中输入网址后会看到网站的内容,这个过程简单来说就是浏览器从服务器中获取网站信息,经过渲染后将效果呈现给用户,但过程细节上则包含了网络传输层的TCP协议、网络应用层的HTTP协议、SOCKET通信、服务器和客户端的开发等等技术点,涉及面比较广,对初学者来说存在一定的难度。笔者结合了自身学习的经验选取一些关键技术来和大家进行分享,对技术的原理和实现进行概括和说明。

Web访问过程

浏览器访问网站总体来说可以分为以下几步:
1)第一步:浏览器向DNS服务器发起DNS请求,DNS服务器解析域名后返回域名对应的网站服务器IP地址
2)第二步:浏览器获取IP地址后向网络服务器发送一个HTTP请求
3)第三步:网络服务器解析浏览器的请求后从数据库获取资源,将生成的html文件封装至HTTP 响应包中,返回至浏览器解析
4)第四步:浏览器解析HTTP 响应后,下载html文件,继而根据文件内包含的外部引用文件、图片或者多媒体文件等逐步下载,最终将获取到的全部文件渲染成完整的网站页面。
下图抓包显示了访问“www.baidu.com”时,DNS请求和响应、HTTP请求和响应

TCP连接过程

浏览器与Web服务器之间的请求和响应是使用HTTP协议进行的,但HTTP协议只是应用层使用的协议,传输层进行的数据通信则是通过TCP协议来保证的。

TCP协议是面向连接的协议,总体包括建立连接、数据传输和关闭连接这三个过程,建立连接采用“三次握手”方式来完成,连接成功后即可发送数据,在关闭连接之前,为确保数据正确传递完毕,需要采用“四次挥手”方式关闭连接。

第一次握手:客户端发送连接请求报文段至服务器

第二次握手:服务器收到报文后确认连接请求,向客户端返回应答报文

第三次握手:客户端收到响应后检查ACK(num)和ACK(flag)值,并向服务器给出确认

完成三次握手,客户端与服务器开始传送数据

第一次挥手:客户端发送释放请求报文段至服务器,并不在发送数据

第二次挥手:服务器收到释放连接请求后向客户端返回应答报文。此时连接处于半关闭状态,即客户端不再向服务器发送数据,但如果服务器仍有数据要发送给客户端,仍可以发送,客户端只要正确收到数据,仍应向服务器发送确认

第三次挥手:若服务器不再向客户端发送数据,则服务器发送连接释放应答至客户端,关闭反方向连接

第四次挥手:客户端收到响应后向服务器给出确认,释放从服务器至客户端方向的连接

完成四次挥手,客户端与服务器全部连接完全释放

也许有人会有疑惑,为什么建立连接协议是“三次握手”,而关闭连接却是“四次挥手”呢?由于TCP连接是全双工的,当关闭连接时,服务器收到客户端的FIN报文通知,仅仅表示客户端没有数据发送给服务器,但未必服务器所有的数据都发送给了客户端,可能还需要发送一些数据后再关闭连接。所以ACK报文和FIN报文分开发送形成了“四次挥手”。

Socket编程

在网络编程中不可避免地会使用到Socket编程,Socket将TCP/IP协议封装成API接口,使得程序员更方便地使用TCP/IP协议栈。Socket是以"打开—读/写—关闭"模式实现,以TCP协议通讯的Socket为例,交互流程大致如下,这里从服务器的角度对流程进行介绍:

创建socket()。socket()根据指定的协议族(IPv4/IPv6)、通信类型(TCP/UDP)在sockfs文件系统中分配一个使用socket描述字关联的资源,进程可以像访问一个已经打开的文件一样访问socket资源。

绑定bind()。bind()在这个socket上绑定一个指定的端口号和IP地址。网络通信归根结底可视为不同计算机上的进程间通讯,IP地址只能确定进程所在的计算机,而结合端口号可以唯一确定整个网络中的一个网络进程。当IP地址为INADDR_ANY(0)时,表示本地计算机的默认IP地址。

监听listen()。服务器socket端口一直处于等待状态,监听网络中所有客户端对端口号请求,随时准备接收客户端发来的连接
接受accept()。服务器socket监听到客户端请求之后,将请求放在等待队列中,accept()从等待队列中提取连接请求,创建一个新的socket进行操作,而原来所监听的socket不受影响。

读/写write()/read()。发送内容即向socket写入内容,读取内容即从socket获取内容

关闭close()。close()关闭socket。

前端与后端

浏览器显示的网页即为web前端界面,提供用户与网站进行交互的可视化接口,而web后端服务主要指在服务器中执行的逻辑运算和数据处理,它为前端提供着访问服务。所谓的前后端只是从代码被执行的位置来区分的,前端代码在用户面前被执行,后端代码在遥远的服务器上被执行。但是,无论前端或后端代码,都是存放在服务器上的,只是当浏览器请求的时候,从服务器发送过去而已。

通常情况下网页的实现是由HTML、CSS和Javascript三者结合完成的,HTML是一种标记语言,负责网页的结构,由HTML的标签元素和文本编写的文档可被浏览器描述为一幅网页,CSS渲染网页元素的样式,而Javascript脚本给网页增加了动态的行为,比如响应用户的行为等。当浏览器载入页面内容时,通常会从上往下顺序执行<script>标记之间的Javascript脚本,当页面载入完成,并且所有脚本执行完成后,浏览器则调用事件处理程序来响应用户的行为。

Web服务器

Web服务器是运行在物理服务器上的一个程序,永久地等待客户端(主要是浏览器,比如Chrome,Firefox等)发送请求。Web服务器通过HTTP协议与客户端通信,当收到请求之后,如果是静态文件的话Web服务器可直接返回,如果不是静态文件的话需要有一个Web应用服务器根据不同的请求处理对应的业务逻辑生成相应的响应,如下图所示。

目前在UNIX和LINUX平台下使用最广泛的免费Web服务器有Apache和Nginx。Nginx是高效的Web服务器和反向代理服务器,可以用作负载均衡,与Apache相比,Nginx支持高并发,可以支持百万级的TCP连接,十万级别的并发连接,部署简单,内存消耗少,成本低,虽然动态请求处理没有Apache丰富,但Nginx支持uWSGI的uwsgi协议,可将动态请求传递至uWSGI处理。

为了简化Web网站的开发,使开发者可以专注于编写业务逻辑代码而无需关心Web应用服务器内各模块连接之类的重复性工作,继而在Web应用服务器上产生了Web框架。MVC是众所周知的Web框架设计模式,即将应用程序分解成model(模型)、view(视图)和 controller(控制器)三个组成部分。用户输入 URL,客户端发送请求,控制器(Controller)首先会拿到请求,然后用模型(Models)从数据库取出所有需要的数据进行必要的处理,将处理后的结果发送给视图(View),视图利用获取到的数据进行渲染生成 Html返回给客户端。MVC设计模式将业务逻辑、数据、界面显示分离,业务逻辑聚集到一个模块中,使得在更改界面时无需重新编写业务逻辑,提高网站的维护性。基于Python的Web框架如Django、tornado、flask、webpy等都在这个范围内进行不同的调整。

Ajax动态交互技术

在上述web应用工作的原理中,我们通过HTTP协议访问一个在服务端存在的文件,服务器可以找到该文件并将其内容封装到HTTP请求中,以消息体的形式返回给客户端。不过这种方式只能访问静态的页面,无法与后端数据库进行交互。既然用户需要通过web前端实时与后端数据库进行交互,那么网页也需要动态的更新,如果每次更新一个数据都通过重新获取Html文件的方式来实现势必会导致网络负荷加重,页面加载迟缓。而Ajax技术可以很好的解决这个问题。

Ajax即异步JavaScript和XML,是一种创建交互式网页的技术,可以不重新加载整个网页的情况下更新部分 网页。目前jQuery库提供多个与AJAX相关的方法。通过 jQuery AJAX方法,能够使用HTTP Get和HTTP Post从远程服务器上请求文本、HTML、XML或JSON,同时能够把这些外部数据直接载入网页被选元素中。

作为web开发人员广泛采用的JavaScript封装库之一的jQuery库,它可以极大地简化我们的JavaScript编程,缓解浏览器之间不兼容的影响,要知道在不同浏览器中进行web网页的兼容性测试也是一个不小的工作量。我们可以通过一个简单的例子发现jQuery库的优势所在:

$("p.neat").addClass("ohmy").show("slow"); 

通过以上简短的代码,开发者可以遍历“neat”类中所有的p元素,然后向其增加“ohmy”类,同时以动画效果缓缓显示每一个段落。开发者无需检查客户端浏览器类型,无需编写循环代码,无需编写复杂的动画函数,仅仅通过一行代码就能实现上述效果。jQuery的口号“最少的代码做最多的事情”果真名副其实,它把JavaScript带到了一个更高的层次。

对于交互的数据格式,可采用JSON(JavaScript Object Notation),它是一种轻量级的数据交换格式,采用完全独立于编程语言的文本格式来存储和表示数据。JSON键值的层次结构简洁清晰,易于阅读和编写,使得 JSON 成为理想的数据交换语言。举个例子来理解JSON数据格式:

{//JSON键/值对
“'wJsona'”:”kkk”
“'wjsonb'”:”12”
“'wjsonc”:”80”
}
文档对象模型

DOM(文档对象模型),它是W3C组织推荐的处理可扩展标记语言(HTML XML)的标准编程接口,它将文档中的对象组织在一个树形结构模型中,因此网页被加载时整个文档映射为一个由层次节点组成的文件,并且以面向对象方式描述了文件中各对象的行为、属性以及这些对象之间的关系,通过 JavaScript可对HTML文档中所有对象进行访问和操作,如动态地添加、删除和修改HTML元素和属性,改变页面中所有CSS样式,也能够对页面中的所有事件做出反应 。

如下图所示,每个方框是文档的一个节点,总共包括三种节点,树形的根部是文档(Document)节点,代表整个文档,元素(Element)节点代表了HTML中的元素,文本(Text)节点代表了文本。同时节点树中的节点彼此拥有层级关系,如下图所示,<html> 节点是根节点,下一级为<head> 和 <body> 节点,他们拥有相同父节点,属于同级的同胞节点,以此类推。

创建DOM节点

var oDiv = document.createElement('div');

添加样式:(Style 对象属性设置样式/Class继承外部文件定义的样式)

document.getElementById("id").style.property="值"
object.className=classname

插入DOM节点:(把节点插入到父节点的末尾/把节点插入到父节点的某个兄弟节点的前面)

document.body.appendChild(oDiv); //把div插入到body中,并且位于末尾
var oP = createElement('p');  //创建一个p节点
document.body.insertBefore(oP,oDiv); //把p节点插入到div的前面

位置的定位排布:CSS的position属性建立了元素布局所用的定位机制,我们可以将元素显示在页面中的任何位置。

总结

Web开发技术除了以上所述的基础技术外,还包括了其他种种客户端和服务端的技术,比如网页插件、服务器的架构及部署、Python/Java等后端编程技术等,大家可以沿着技术进阶之路逐步加深学习,夯实基础知识、加强编程基本功力,早日成为大牛。

15人推荐
随时随地看视频
慕课网APP