用 Python 撸一个 Web 服务器-第1章:Web 开发简介

本文涉及的产品
.cn 域名,1个 12个月
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
简介: 用 Python 撸一个 Web 服务器-第1章:Web 开发简介

前言

Web 开发技术一直在高速发展,各种新奇概念与框架层出不穷,尤其在 Web 前端领域,几年前还是 jQuery 的天下,而如今在 Vue、React 等框架面前也显得廉颇老矣。

不过,虽然各种框架技术日新月异,但 Web 开发的核心概念与本质依旧不曾改变,本教程将通过一个 Todo List 应用带你探索 Web 开发基本原理,只有真正明白了 Web 开发的核心基础,才能更轻松的应对新框架与技术。

Web 开发简介

我们常见的软件种类有桌面软件、移动 APP以及网页应用等,Web 开发通常就是在开发网页应用。桌面软件、移动 APP 需要先安装在 Windows、Android 等宿主机才能使用,每个客户端每次升级更新软件时都需要重新下载并安装。而 Web 应用所依赖的客户端是浏览器,实际数据都存储在远程服务器端,如果应用需要升级,那么只需要升级服务器,所有用户通过浏览器打开网页时都将实时获取最新的数据,这也是 Web 开发能够流行起来的很重要的原因。

HTTP 简介

要学习 Web 开发,首先要明白什么是 HTTP 协议,因为 Web 开发就是建立在 HTTP 协议之上的。

在浏览器地址栏输入网址 https://www.jd.com/ 将得到京东商城首页。我们在浏览器页面中看到的所有数据都是服务器通过 HTTP 协议传输过来的。

HTTP 协议中文叫超文本传输协议,可以拆分成三部分理解:超文本、传输、协议。

所谓超文本就是 HTML、CSS、图片、视频等内容的集合。传输既超文本内容从浏览器(客户端)到服务器或从服务器到浏览器之间的传输过程。而协议是规范,大家约定俗成的规约既是协议。

HTTP 基于请求 —— 响应模型,浏览器向服务器的某个网址发起请求,服务器响应浏览器对应的资源。以下就是一个 HTTP 请求 —— 响应的模型图。

HTTP 模型

左侧是浏览器,右侧是服务器。浏览器和服务器之间通讯是通过文本传输来完成的。浏览器发起请求时发送的数据叫作请求报文,得到的服务端响应的数据叫作响应报文。下图示展示了请求报文和响应报文的格式。

HTTP 请求和响应报文

根据图示可以看到,无论是请求报文还是响应报文基本都分为四个部分,每个部分之间以 \r\n 作为换行分隔符。

请求报文包含请求行、报文首部、空行、报文主体四个部分。

响应报文包含状态行、报文首部、空行、报文主体四个部分。

在请求报文中,请求行和报文首部可以看成一个整体叫作请求头,报文主体又叫请求体。

在响应报文中,状态行和报文首部可以看成一个整体叫作响应头,报文主体又叫响应体。

如何在 Chrome 浏览器中查看请求与响应的报文信息呢?浏览器页面任意位置点击鼠标右键 —— 选择检查,就能够在页面底部显示 Chrome 开发者工具。点击 Elements 选项卡,你就能够看到网页的源代码,也就是服务器的响应数据。

Elements

点击 Network 选项卡,就能够看到所有请求、响应记录。

Network

每一行记录即为一个请求,为什么只是在地址栏里输入了 https://www.jd.com/ 会出现这么多请求呢?我们知道,HTML 中不止可以写简单的文本标签,还可以写 imgvideo 等多媒体标签加载图片或视频,以及 linkscript 等标签来加载 CSS 样式 和 JavaScript 脚本。浏览器在得到服务器的第一个响应时,会检查服务器返回的 HTML 页面,如果页面源码中包含这些特殊的标签,浏览器就会针对每一个标签专门发起一次请求。

点击第一个请求,在右侧将会显示该请求及响应信息。找到 Request Headers 点击右侧的 view source,将会看到此次请求的请求头信息。

请求头

请求头

第一行 GET / HTTP/1.1 即为请求行。它由三个部分组成:请求方法、请求地址、HTTP 协议版本号,分别对应 GET/HTTP/1.1。每个部分之间通过一个空格隔开。

HTTP 请求方法有很多,不过最常见的只有四种:POSTDELETEPUTGET 分别对应增、删、改、查四个操作。由于我们只是想查看京东首页,所以这里发送的是 GET 请求。

请求地址 / 代表首页,你可能看过如 /index/index.html 等类似的地址,其实这只是一个约定俗成的做法,它们都代表首页。

现在最常用的 HTTP 版本即为 1.1。虽然 HTTP 2.0 早已发布,不过目前来说普及率依旧不是很高。所以现在大可不必纠结版本的问题。

从第二行开始,所有内容都是诸如 Key: Value 这种键值对的形式组合成的,我们管每一组键值对都叫作请求首部字段,这些首部字段加在一起就是请求的报文首部,一般会直接叫请求头。

其中最重要的请求首部字段就是 Host: www.jd.com 这一行,因为只有这一行是 HTTP 协议明确规定为必传的首部字段,其他请求首部字段都是非必传字段。Host: www.jd.com 的作用是当服务器上部署了多个网站,那么服务器就会根据这一行的信息来确定浏览器到底想访问哪个网站。

Connection: keep-alive 代表长连接,User-Agent 标识了浏览器信息,Accept 代表浏览器能够接收的报文格式,其他的请求首部字段可以等我们用到了再做说明。

在 HTTP 请求报文中,还缺少一个空行和请求体是我们目前没有看到的。实际上虽然我们是点击浏览器的 view source 功能来查看请求报文信息,但它仍然是浏览器处理过的数据,并不是原始数据,所以空行是看不到的。而此次请求为 GET 请求,通常 GET 请求是没有请求体的,所以请求体被省略了。

一个 HTTP GET 请求大概长这样:

GET / HTTP/1.1
Host: www.jd.com
Connection: keep-alive
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9

一个 HTTP POST 请求大概长这样:

POST /login HTTP/1.1
Host: www.jd.com
Connection: keep-alive
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
username=test&password=pass

上面 POST 请求示例中 username=test&password=pass 即为请求体。

需要注意,以上请求报文中每一个换行都是用 \r\n 来标识的,这一点在后面实际开发的章节中就能体会到。

分析完请求报文,接下来分析下响应报文。找到 Response Headers 同样点击右侧的 view source,将会看到此次请求的响应头信息。

响应头

响应头

第一行 HTTP/1.1 200 OK 即为状态行。它同样由三部分组成:HTTP协议版本号、状态码、当前状态码对应的原因短语,分别对应 HTTP/1.1200OK。每个部分之间仍然通过一个空格隔开。

其中状态码用来告知服务器返回的响应状态,为一个数字。状态码大概分为四类:2XX3XX4XX5XX,分别对应成功、重定向、客户端错误、服务端错误。所以状态码为 200 表示请求成功。

原因短语 OK 其实并不是很重要,它主要是给客户端返回一个人类可读的短语,来标识请求结果,对浏览器来说没什么作用。

响应首部字段同样是 Key: Value 这种键值对形式,并且有些是和请求首部字段一样的,称为通用首部字段,如 Connection: keep-alive 同样存在于响应首部字段。还有些字段是和请求首部字段搭配着使用的,如你所见 Content-Type 字段就是搭配请求首部字段中的 Accept 来使用的,Accept 是浏览器用来告诉服务器它能够接收的数据格式,而 Content-Type: text/html 标识了服务器返回的数据格式为 html。其他的响应首部字段可以等我们用到了再做说明。

同样的,响应报文中的空行并不会在浏览器中展现出来,不过响应体是可以在浏览器中看到的。

响应体

当前请求的响应体实际上就是服务器返回的 HTML 源码。

一个 HTTP 响应大概长这样:

HTTP/1.1 200 OK
Connection: keep-alive
Content-Type: text/html
<html>XXX</html>

URL 简介

介绍完 HTTP 协议基础,我们再来简单介绍下 URL

京东首页的网址是 https://www.jd.com/,这就是一个 URLURL 中文叫作统一资源定位符。URL 的作用是在网络中唯一的标记一个资源。

你可能听说过 URI,实际上 URLURI 的一个子集。在基础学习阶段,我们并不需要弄清楚它们之间到底有什么差别,只需要把我们常见的网址统称为 URL 即可。

一个 URL 的完整格式如下:

scheme://user:passwd@host:port/path?query#fragment

每一个部分代表含义如下:

scheme:协议名,表示资源使用哪种协议,http 就代表了 HTTP 协议,file 代表文件协议。

://:这个是固定写法,记住就好,没必要深究。

user:passwd@:身份信息,表示访问主机时需要提供的用户名和密码,但这种将隐私信息完全暴露在外部的作法已经几乎没人使用了。

host:port:表示资源所在的主机名和端口号。主机名为 IP 地址或域名,必须要有,HTTP 协议默认端口号是 80,可以省略,其他端口号则不可省略。

path:标识资源所在位置。它采用类似 Unix 系统的目录风格,必须以 / 开头,如果是多级路径,可以写成 /a/b/c 这种形式。

query:查询参数,在路径之后第一个 ? 开始(不包含?)到 # 之前结束,所有的内容都是查询参数,一个参数的格式为 key=value,如果存在多个参数,中间用 & 隔开。假如我们需要对数据做分页处理就可以使用这个参数,如 page=1&offset=20 表示需要获取第一页的数据,每页数据 20 条。这时候服务器端就可以解析到这个参数并返回对应的数据。

fragment:最后一部分为片段标识符。也可以将其叫做锚点,从 # 开始,浏览器可以根据锚点跳转到页面指定位置,但这个参数是不会被发送到服务器端的,所以开发服务器端通常不太需要关心。

下面通过对一个实际的 URL 地址进行分析来加强理解。

以下图示为在京东首页搜索 Python书籍后浏览器地址栏 URL 截图。为了能够更清晰的说明问题 URL 部分略有删减。

URL

我们可以将 URL 复制出来:

https://search.jd.com/Search?keyword=python%E4%B9%A6%E7%B1%8D&enc=utf-8

以上 URL 按标准格式拆分如下:

scheme: https
host:port: search.jd.com
path: /Search
query: keyword=python%E4%B9%A6%E7%B1%8D&enc=utf-8

你应该已经发现上面复制出来的 URL 和截图中的有些不同。

首先我们复制出来的 URL 是以 https 开头,而浏览器中却是以 search 开头,其实这是浏览器为了让 URL 更加可读,而将 https:// 隐藏了,实际上它仍然是存在的。

你可能有个疑惑,我们上面一直在介绍 HTTP 协议,一个完整的 URL 是以 http 开头的。但实际上京东网站的 URL 都是以 https 开头的。其实 https 是基于 http 的,只是在 http 的基础上又加了一个安全套接层,默认端口 443,HTTP 协议传输数据都是明文传输,HTTPS 协议传输数据是经过加密的,所以使得数据的传输更加安全,仅此而已。本教程不会使用 HTTPS 协议,故此不做过多讲解。

还有一个较大的差异就是在浏览器地址栏中看到的查询参数 Python书籍 复制出来以后就变成了 python%E4%B9%A6%E7%B1%8D。这是 URL 编码造成的,通常在 URL 中只能使用 ASCII 码,并且 URL 本身会使用如 ?& 等符号作为分隔符。这就导致了很多特殊符号或者 ASCII 以外的字符(如中文)不能够直接使用,所以就规定了一种转码规范,将不能直接用于 URL 的字符通过转义操作使其变为可用字符。这就是 书籍 两个字符变成了 %E4%B9%A6%E7%B1%8D 的原因。在浏览器地址栏中能够正常显示同样是浏览器为了让 URL 更加可读做的特殊处理。URL 转义具体规则可以查看相关文档进行学习。

TCP/IP 简介

多个计算机之间通讯靠的是网络协议,最早的计算机厂商生产的计算机只能跟自家的计算机通讯,为让所有计算机之间都能够通讯就有了 TCP/IP 协议。这就比如几个人对话,有的说汉语、有的说英语、有的说日语,大家谁也听不懂其他人说话,所以最后大家都规定用一种语言来交流一样。

TCP/IP 协议并不是单个的协议,它是一个协议族,包含了很多种网络通讯协议,HTTP 协议也在其中。在网络中两台计算机之间如果需要通讯,就要知道对方在哪,所以就有了 IP 地址。就像我们要给别人发快递,那么就要知道对方的家庭住址一样。现在常用的 IP 地址为 IPv4 版本,格式如 192.168.3.14,最新版本是 IPv6,格式如 ABCD:EF01:2345:6789:ABCD:EF01:2345:6789

有了 IP 地址还不够,就像你把快递邮寄到一个家庭住址,但家里有五口人,你还要确定这个快递是寄给谁的。端口的作用就是干这个的。计算机通过端口号区分收到的信息该转发给哪个软件。

IP 地址加上端口号就是上面介绍的 URLhost:port 部分,如 192.168.3.14:80。但 IP 地址是一串数字,不容易记住,所以就有了域名。www.jd.com 就是京东的域名。我们在浏览器中输入这个域名时,计算机会自动将其转换成 IP 地址加端口号的形式。这个转换过程是通过一个叫 DNS 解析的技术。它能够将域名和 IP 之间的关系做绑定,知道了域名它就能查出其对应的 IP 地址是多少。

HTTP 协议是建立在 TCP/IP 协议之上的,HTTP 的数据传输依靠的是 TCP 协议。总结起来就是 TCP 用来传输数据,HTTP 用来规范数据传输格式。

扩展

从浏览器地址栏输入网址 https://www.jd.com/ 到看见京东网站首页经历了什么?

  1. 浏览器从地址栏获取 URL
  2. 浏览器或操作系统通过 DNS 解析将 URL 中域名和端口号解析成对应的 IP 地址和端口号
  3. 浏览器通过 TCP 与服务器建立连接
  4. 浏览器向服务器发送请求报文
  5. 服务器收到请求报文后做对应的处理,将处理结果组装成响应报文返回给浏览器
  6. 浏览器解析响应报文,渲染页面

以上就是从浏览器地址栏输入网址 https://www.jd.com/ 到看见京东网站首页所经历的过程概述。

如果你对 Web 开发完全零基础,看了以上我对 HTTP 协议的简介,感觉不是很明白的话,那么我推荐你可以看一本叫作《图解HTTP》的书,看完后再来学习本教程能够达到事半功倍的效果。

开发环境

本教程项目开发环境如下:

  • Python:Python3.7
  • 浏览器:Chrome83
  • 开发工具:PyCharm 2020.1
  • 操作系统:macOS 10.15

有 Python 基础的同学想必搭建开发环境肯定不在话下,所以具体搭建过程这里不再做过多介绍,需要强调的一点是浏览器我只推荐 Chrome 或者 Firefox,这样能够得到更好的开发体验。

相关文章
|
2月前
|
XML JSON API
ServiceStack:不仅仅是一个高性能Web API和微服务框架,更是一站式解决方案——深入解析其多协议支持及简便开发流程,带您体验前所未有的.NET开发效率革命
【10月更文挑战第9天】ServiceStack 是一个高性能的 Web API 和微服务框架,支持 JSON、XML、CSV 等多种数据格式。它简化了 .NET 应用的开发流程,提供了直观的 RESTful 服务构建方式。ServiceStack 支持高并发请求和复杂业务逻辑,安装简单,通过 NuGet 包管理器即可快速集成。示例代码展示了如何创建一个返回当前日期的简单服务,包括定义请求和响应 DTO、实现服务逻辑、配置路由和宿主。ServiceStack 还支持 WebSocket、SignalR 等实时通信协议,具备自动验证、自动过滤器等丰富功能,适合快速搭建高性能、可扩展的服务端应用。
126 3
|
28天前
|
设计模式 前端开发 数据库
Python Web开发:Django框架下的全栈开发实战
【10月更文挑战第27天】本文介绍了Django框架在Python Web开发中的应用,涵盖了Django与Flask等框架的比较、项目结构、模型、视图、模板和URL配置等内容,并展示了实际代码示例,帮助读者快速掌握Django全栈开发的核心技术。
139 45
|
10天前
|
开发框架 JavaScript 前端开发
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势。通过明确的类型定义,TypeScript 能够在编码阶段发现潜在错误,提高代码质量;支持组件的清晰定义与复用,增强代码的可维护性;与 React、Vue 等框架结合,提供更佳的开发体验;适用于大型项目,优化代码结构和性能。随着 Web 技术的发展,TypeScript 的应用前景广阔,将继续引领 Web 开发的新趋势。
25 2
|
1月前
|
缓存 监控 Linux
Python 实时获取Linux服务器信息
Python 实时获取Linux服务器信息
|
24天前
|
前端开发 API 开发者
Python Web开发者必看!AJAX、Fetch API实战技巧,让前后端交互如丝般顺滑!
在Web开发中,前后端的高效交互是提升用户体验的关键。本文通过一个基于Flask框架的博客系统实战案例,详细介绍了如何使用AJAX和Fetch API实现不刷新页面查看评论的功能。从后端路由设置到前端请求处理,全面展示了这两种技术的应用技巧,帮助Python Web开发者提升项目质量和开发效率。
40 1
|
2月前
|
Python
Socket学习笔记(二):python通过socket实现客户端到服务器端的图片传输
使用Python的socket库实现客户端到服务器端的图片传输,包括客户端和服务器端的代码实现,以及传输结果的展示。
145 3
Socket学习笔记(二):python通过socket实现客户端到服务器端的图片传输
|
27天前
|
XML 安全 PHP
PHP与SOAP Web服务开发:基础与进阶教程
本文介绍了PHP与SOAP Web服务的基础和进阶知识,涵盖SOAP的基本概念、PHP中的SoapServer和SoapClient类的使用方法,以及服务端和客户端的开发示例。此外,还探讨了安全性、性能优化等高级主题,帮助开发者掌握更高效的Web服务开发技巧。
|
29天前
|
安全 数据库 开发者
Python Web开发:Django框架下的全栈开发实战
【10月更文挑战第26天】本文详细介绍了如何在Django框架下进行全栈开发,包括环境安装与配置、创建项目和应用、定义模型类、运行数据库迁移、创建视图和URL映射、编写模板以及启动开发服务器等步骤,并通过示例代码展示了具体实现过程。
43 2
|
2月前
|
IDE 网络安全 开发工具
IDE之pycharm:专业版本连接远程服务器代码,并配置远程python环境解释器(亲测OK)。
本文介绍了如何在PyCharm专业版中连接远程服务器并配置远程Python环境解释器,以便在服务器上运行代码。
350 0
IDE之pycharm:专业版本连接远程服务器代码,并配置远程python环境解释器(亲测OK)。
WK
|
29天前
|
安全 Java 编译器
C++和Java哪个更适合开发web网站
在Web开发领域,C++和Java各具优势。C++以其高性能、低级控制和跨平台性著称,适用于需要高吞吐量和低延迟的场景,如实时交易系统和在线游戏服务器。Java则凭借其跨平台性、丰富的生态系统和强大的安全性,广泛应用于企业级Web开发,如企业管理系统和电子商务平台。选择时需根据项目需求和技术储备综合考虑。
WK
54 0