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

news2025/1/12 8:43:51

前言

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 模型

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

HTTP 请求和响应报文

HTTP 请求和响应报文

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

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

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

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

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

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

Elements

Elements

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

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 的完整格式如下:

1

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

我们可以将 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,这样能够得到更好的开发体验。

原文出处: https://jianghushinian.cn

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1820051.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2024 年十大关键渗透测试发现:您需要了解的内容

编辑信息技术 (IT) 专业人员在坏人之前发现公司弱点的最有效方法之一就是渗透测试。通过模拟现实世界的网络攻击&#xff0c;渗透测试&#xff08;有时称为 pentests&#xff09;可以提供有关组织安全状况的宝贵见解&#xff0c;揭示可能导致数据泄露或其他安全事件的弱点。 自…

zerotier自建moon方法

简介 使用zerotier已经有一段时间了&#xff0c;现在偶尔会出现服务器连接不上的情况。我就想自己建个moon来试试。记录一下过程&#xff0c;用作备忘录。 准备工作 准备一个有公网IP的云主机。我用的是“三丰云”&#xff0c;速度很快同时提供"免费虚拟主机"和“免费…

docker 部署nginx多级子域名(三级四级...)映射不同web项目,访问不同路径地址

一、背景 只有一台服务器&#xff0c;一个顶级域名&#xff0c;现在需要根据不同子域名访问不同web项目&#xff0c;比如 # 管理后台 cms.biacu.com# 客户端h5 h5.biacu.com# 四级域名 h5.s.biacu.com同时&#xff0c;不同web项目放在不同位置 二、 1、在云服务器上&#x…

u-boot(三) - 编译

一&#xff0c;u-boot编译过程总结 编译时的Makefile log&#xff1a; //链接得到ELF格式的u-boot arm-buildroot-linux-gnueabihf-ld.bfd -pie --gc-sections -Bstatic -Ttext 0x87800000 -o u-boot -T u-boot.lds arch/arm/cpu/armv7/start.o --start-group arch/arm/c…

雷军出手,光储充一体化赛道可太行了

雷军出手&#xff0c;特斯拉、宁德时代、奥能电源持续加码&#xff0c;光储充一体化赛道可太行了 近几年&#xff0c;各地光储充一体化项目遍地开花&#xff0c;正式投入运营的新闻接连不断。被视为全球能源转型重要驱动力的光储充一体化&#xff0c;已成为各大企业竞相入局的新…

放弃Venn-Upset-花瓣图,拥抱二分网络

写在前面 让点随机排布在一个区域&#xff0c;保证点之间不重叠,并且将点的图层放到最上层&#xff0c;保证节点最清晰&#xff0c;然后边可以进行透明化&#xff0c;更加突出节点的位置。这里我新构建了布局函数 PolyRdmNotdCirG 来做这个随机排布。调用的是packcircles包的算…

现代X86汇编-C和ASM混合编程举例

端午假期安装好了vs c2022,并写了个简单的汇编代码&#xff0c;证明MASM真的可以运行。今天需要搞一个实实在在的C和ASM混合编程的例子&#xff0c;因为用纯汇编的求伯君写WPS的时代一去不复返了。个别关键函数用汇编&#xff0c;充分发挥CPU的特色功能&#xff0c;偶尔还是需要…

论文阅读:H-ViT,一种用于医学图像配准的层级化ViT

来自CVPR的一篇文章&#xff0c;https://openaccess.thecvf.com/content/CVPR2024/papers/Ghahremani_H-ViT_A_Hierarchical_Vision_Transformer_for_Deformable_Image_Registration_CVPR_2024_paper.pdf 用CNNTransformer混合模型做图像配准。可变形图像配准是一种在相同视场…

计算机体系结构重点学习

从外部I/O与上层应用交互的整体软硬件过程 上层应用发出I/O请求&#xff1a;上层应用程序&#xff0c;如一个文本编辑器、网络浏览器或者任何软件应用&#xff0c;需要读取或写入数据时&#xff0c;会通过调用操作系统提供的API&#xff08;如文件操作API、网络操作API等&…

CATIA P3 V5-6R 中文版软件下载安装 达索CATIA三维设计软件获取

CATIA的建模和装配能力堪称业界翘楚。其强大的建模工具能够轻松应对各种复杂的几何形状和结构&#xff0c;帮助设计师们快速构建出精准的产品模型。同时&#xff0c;装配模块则能够实现零部件的快速装配&#xff0c;大大提高了设计效率。 在分析和仿真方面&#xff0c;CATIA同样…

基于python多光谱遥感数据处理、图像分类、定量评估及机器学习

原文链接&#xff1a;基于python多光谱遥感数据处理、图像分类、定量评估及机器学习 普通数码相机记录了红、绿、蓝三种波长的光&#xff0c;多光谱成像技术除了记录这三种波长光之外&#xff0c;还可以记录其他波长&#xff08;例如&#xff1a;近红外、热红外等&#xff09;光…

【技术】MySQL 8.4 免安装版配置

MySQL 8.4 免安装版配置 官网下载压缩包解压文件创建配置文件初始化数据库安装MySQL服务链接数据库修改密码 官网下载压缩包 从MySQL官网下载压缩包&#xff0c;官网&#xff1a;https://www.mysql.com/ 头部菜单点击【DOWNLOADS】&#xff0c;跳转到下载页面。在页面底部点击…

如何通过逆向分析法挖掘真实需求?

逆向分析法从现有问题或现象出发&#xff0c;反向追溯其根本原因&#xff0c;以揭示隐藏需求和潜在问题。此方法有助于深入理解用户的真实需求&#xff0c;提高需求分析质量和效率&#xff0c;优化用户体验&#xff0c;提高用户满意度和忠诚度。如果缺乏逆行分析法&#xff0c;…

4.1 Python 字符串类型常用操作及内置方法

0. 序列类型 序列是一种数据存储方式, 用来存储一系列的数据. 在内存中, 序列使用连续的内存空间用来存放多个值.序列类型的变量存储序列对象的地址, 而不是直接存在值的地址. 序列对象保存索引和对象的绑定关系.s ABCDprint(id(s), type(s), s) # _ 2050757126000 &…

电商开发者必读:微店商品详情API接口全解析

微店作为一个流行的电商平台&#xff0c;提供了丰富的API接口供开发者使用。详细介绍商品详情API接口的使用方法&#xff0c;帮助开发者快速获取商品信息&#xff0c;实现商品信息的自动化展示和管理。 1. 接口简介 微店商品详情API接口允许开发者通过商品ID获取商品的详细信…

三星公布尖端芯片进展 | 百能云芯

三星电子在本周三举办的年度晶圆制造盛会上&#xff0c;揭开了未来多项技术革新的神秘面纱&#xff0c;并宣布其晶圆制造业务将整合全球领先的记忆芯片、晶圆制造及封装服务&#xff0c;为AI芯片客户提供一站式服务&#xff0c;以加速其生产进程。 三星强调&#xff0c;客户仅需…

qt(使用c++建立图形化界面)

建立QQ页面 MainWindow::MainWindow(QWidget *parent): QMainWindow(parent) {//1:设置窗口标题this->setWindowTitle("QQ");//2:重新设计窗口大小this->resize(540,420);//3:设置窗口小图标 添加QIcon头文件 注意路径中替换/this->setWindowIcon(QIcon(&q…

Windows本地使用SSH连接VM虚拟机

WIN10 VM17.5 Ubuntu:20.04 1.网路设置 1)选择编辑->更改设置 配置完成 2.修改了服务器文件&#xff0c;修改sshd配置&#xff0c;在此文件下/etc/ssh/sshd_config&#xff0c;以下为比较重要的配置 PasswordAuthentication yes PermitRootLogin yes PubkeyAuthenticat…

【安装笔记-20240613-Linux-在 OpenWrt 的 LuCI界面支持命令行调试】

安装笔记-系列文章目录 安装笔记-20240613-Linux-在 OpenWrt 的 LuCI界面支持命令行调试 文章目录 安装笔记-系列文章目录安装笔记-20240613-Linux-在 OpenWrt 的 LuCI界面支持命令行调试 前言一、软件介绍名称&#xff1a;ttyd主页官方介绍特点 二、安装步骤测试版本&#xf…

远程开发端口转发

应用推荐场景&#xff1a; 1.服务器跑后台&#xff0c;本地出前端应用。 比如Stable Diffusion的大模型打标应用。 2.Docker容器服务器。 对于本地服务想要转出去&#xff0c;跑出来前端。该项能克服虚拟机的端口与ip访问问题。 正文&#xff1a; 涉及的软件&#xff1a; …