在上一篇文章中, 咱们用APIFlask写了一个简单的Hello World程序,相信大家都感受到了其简洁轻便。从这篇文章开始,我们将更加深入、详细的介绍Web 开发 和 Flask/APIFlask

前文我们已经解释了路由是什么,并且还演示了如何绑定多个路由和动态URL,接下来我们更加深入的看一下路由与HTTP的关系。还会了解Flask处理请求与响应的各种方式,如果想要开发Web应用,HTTP协议是无法绕过的。因此本文还会通过具体的Flask来演示相应的HTTP知识。虽然本章的内容很重要,但鉴于内容晦涩难懂,如果感到困惑也不必担心,其中的内容会在后面的实践中逐渐理解。因此我建议你在后面的学习中不断的重读本章节。

系列文章

  1. 后端系列:基本简介与Hello APIFlask! (一)
  2. 后端系列:简述 HTTP(二)

HTTP

在讲到Web开发、HTTP协议时,许多人都会下意识的将客户端理解成了浏览器,这其实是不对的。客户端是指请求访问文本、图像等资源的一端,也就是说客户端除了我们常用的浏览器之外还可以是桌面应用、手机App、小程序、爬虫程序等能发起HTTP请求的一段代码。同理提供资源响应的一端称为服务端,也就是我们这里的后端程序。

HTTP Request

请求是一切的起源,当我们输入URL后,都会向服务器发送一个 HTTP Request。一个标准的 URL 由很多部分组成,以下面这个 URL 为例:

http://127.0.0.1:5000/hello?name=farmer

这个 URL 的各个组成部分如表所示:

信息 说明
http:// 协议字符串,指定要使用的协议
helloapiflask.com 服务器的地址(这里是域名)
/hello?name=farmer 要获取的资源的路径(path),类似UNIX的文件目录结构

扩展: 资源路径中?name=farmer部分称为查询字符串,它是包含在资源路径中的

HTTP报文结构

正所谓知其然知其所以然,手撸一个 HTTP服务器 无疑会让我们更加深刻的理解什么是 HTTP,为此本章节先会手撸一个超级简单的 HTTP Server 来浅入浅出的讲解。

下面将会把simple-http-server/server.py的核心代码抽出来讲解,层次结构相对完整代码请移步到仓库中浏览:

simple-http-server/server.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# HTTP报文头
http_header = 'HTTP/1.1 200 OK\r\nContent-Type: text/html'
# HTTP body
http_payload = '<h1>Hello World</h1>'
# HTTP数据帧
http_framework = f'{http_header}\r\n\r\n{http_payload}'
# 创建 socket 对象
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 绑定 IP 和端口
sock.bind(('127.0.0.1', 5000))
client = sock.accept()
# 给客户端发送响应数据
client.sendall(http_framework)
client.close()

从上面这段代码中不难看出,无论是header还是payload都是字符串,而我们平时Web开发中,无论是后端渲染的方式亦或是前后端分离。其实本质上都只是对payload部分的内容进行更改。因为无论是 HTML 还是 JSON 都只是一串字符串罢了~ 因此我们无需太过在意这些小细节,只需要明确我们无论哪种方式,都只是为了将数据传给客户端即可。

有了这样的一个基本概念,我们开始来看一下APIFlaskHTTP 是如何处理的。

Flask/APIFlask中的HTTP

为了更贴近现实,我们以一个真实的URL为例:
http://helloapiflask.com/hello

当我们在浏览器的地址栏中输入这个URL时,浏览器会显示一个问候界面。这背后到底发送了什么?通过上面对 HTTP Server 的讲解你一定可以猜到了,这背后的本质就是上面的例子。只不过在此基础上添加了许多模块,来处理各种路由、请求头、请求体、响应头和响应体等内容。整体的请求响应抽象出来如下图所示:

这是每一个 Web 程序的基本工作模式。如果再进一步,这个模式又包含了许多的工作单元,下图就展示了一个APIFlask程序工作的实际流程。

上图中可以看出,HTTP在整个流程中起到了至关重要的作用,它是客户端与服务端之间沟通的桥梁。

当用户访问URL的时候,浏览器便生成对应的 HTTP Request,经由互联网发送到对应的 Web 服务器。Web服务器接收到请求,通过 WSGI 将 HTTP 格式的请求数据转换成我们的 APIFlask 程序能够处理使用的 Python 数据。在程序中,APIFlask根据请求的URL执行对应的视图函数(view function),获取返回值生成响应。然后响应依次经过 WSGI 转换生成 HTTP 响应,再由 Web 服务器传递,最终给发送出请求的客户端接收,进行对应的响应处理,最后把解析好的数据呈现给用户。

这里的服务器指的是处理请求和响应的 Web 服务器,而不是物理层面的服务器主机

总结

Web 开发本质上其实就是操作(读写) HTTP 协议,因此本章花费了大量的时间精力并通过手撸一个简易的 http 服务器,希望能帮助到读者浅入浅出的理解 http 协议,下一节将深入讲解 APIFlask 中的HTTP与路由模块。