python web开发 网络编程 HTTP协议、Web服务器、WSGI接口

文章目录

    • 1. HTTP协议
    • 2. Web服务器
    • 3. 静态服务器
      • 创建 web_server.py
    • 4. WSGI 接口
      • 4.1 CGI 通用网关接口
      • 4.2 WSGI
      • 4.3 定义 WSGI 接口
      • 4.4 运行 WSGI 服务

learning from 《python web开发从入门到精通》

1. HTTP协议

  • 应用层最主要的协议:HTTP协议(HyperText Transfer Protocol 超文本传输协议)
  • 用户访问网站时,用户浏览器是客户端(向服务器发请求),网站被称为服务器(收到请求,处理后的响应传给客户端),此过程通过 HTTP 协议实现
  • 利用 TCP 在两台计算机(如Web服务器,客户端)之间传输信息,客户端使用 web浏览器发送 HTTP 请求给 web 服务器,服务器发送响应给客户端

2. Web服务器

当在浏览器中输入 url 后:

  1. 浏览器请求 DNS 服务器,进行域名解释,获得 站点 IP 地址
  2. 发送一个 HTTP Request 请求 给拥有该 IP 的主机
  3. 收到服务器返回的 HTTP Response响应,浏览器渲染效果后呈现给用户

Web 服务器工作原理:

  • 建立连接:客户端通过 TCP/IP 协议建立到服务器的 TCP 连接
  • 请求过程:客户端向服务器发送 HTTP协议请求包,请求资源
  • 应答过程:服务器向客户端发送 HTTP协议应答包,如果资源包含动态语言内容,会先进行处理,得到的数据返回客户端,客户端解释 HTML 渲染在屏幕上
  • 关闭连接:断开客户端和服务器

常用请求方法:

  • GET:请求指定页面
  • POST:提交数据(表单或者文件等)
  • HEAD:类似GET,但仅仅获取报头
  • PUT:取代服务器上的指定文档内容
  • DELETE:服务器删除指定页面
  • OPTIONS:允许客户端查看服务器性能

返回状态码:

  • 1**:请求收到,继续处理
  • 2**:成功返回响应
  • 3**:重定向,为了完成请求,必须进一步执行的动作
  • 4**:客户端错误,如语法错误,或者请求无法实现
  • 5**:服务器错误,服务器不能实现一种明显无效的请求

浏览器 按 F12 可以查看相关信息
在这里插入图片描述

3. 静态服务器

  • 纯粹的 HTML 页面被称为 静态页面

例子:创建一个静态服务器,通过该服务器可以访问包含两个静态页面的网站

  • 导航栏的网页 simple_navbar.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>使用bootstrap框架制作导航栏</title><link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.0.2/css/bootstrap.css" rel="stylesheet"><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script><script src="https://cdn.bootcdn.net/ajax/libs/popper.js/2.9.2/cjs/popper-base.js"></script><script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.0.2/js/bootstrap.js"></script></head>
<body><nav class="navbar navbar-expand-sm navbar-light bg-light"><div class="container-fluid"><a class="navbar-brand" href="https://michael.blog.csdn.net/">我的导航</a><button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent"aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"><span class="navbar-toggler-icon"></span></button><div class="collapse navbar-collapse" id="navbarSupportedContent"><ul class="navbar-nav me-auto mb-2 mb-lg-0"><li class="nav-item"><a class="nav-link active" aria-current="page" href="https://michael.blog.csdn.net/">主页</a></li><li class="nav-item"><a class="nav-link" href="#">链接</a></li><li class="nav-item dropdown"><a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button"data-bs-toggle="dropdown" aria-expanded="false">关于作者</a><ul class="dropdown-menu" aria-labelledby="navbarDropdown"><li><a class="dropdown-item" href="#">简历</a></li><li><a class="dropdown-item" href="#">项目</a></li><li><hr class="dropdown-divider"></li><li><a class="dropdown-item" href="contact.html">联系方式</a></li></ul></li><li class="nav-item"><a class="nav-link disabled">商城</a></li></ul><form class="d-flex"><input class="form-control me-2" type="search" placeholder="输入你的关键词" aria-label="Search"><button class="btn btn-outline-success" type="submit">站内搜索</button></form></div></div>
</nav></body>
</html>
  • contact.html,在上面的基础上,添加一些额外的联系信息
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>联系michael</title><link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.0.2/css/bootstrap.css" rel="stylesheet"><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script><script src="https://cdn.bootcdn.net/ajax/libs/popper.js/2.9.2/cjs/popper-base.js"></script><script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.0.2/js/bootstrap.js"></script></head>
<body><nav class="navbar navbar-expand-sm navbar-light bg-light"><div class="container-fluid"><a class="navbar-brand" href="https://michael.blog.csdn.net/">我的导航</a><button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent"aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"><span class="navbar-toggler-icon"></span></button><div class="collapse navbar-collapse" id="navbarSupportedContent"><ul class="navbar-nav me-auto mb-2 mb-lg-0"><li class="nav-item"><a class="nav-link active" aria-current="page" href="https://michael.blog.csdn.net/">主页</a></li><li class="nav-item"><a class="nav-link" href="#">链接</a></li><li class="nav-item dropdown"><a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button"data-bs-toggle="dropdown" aria-expanded="false">关于作者</a><ul class="dropdown-menu" aria-labelledby="navbarDropdown"><li><a class="dropdown-item" href="#">简历</a></li><li><a class="dropdown-item" href="#">项目</a></li><li><hr class="dropdown-divider"></li><li><a class="dropdown-item" href="contact.html">联系方式</a></li></ul></li><li class="nav-item"><a class="nav-link disabled">商城</a></li></ul><form class="d-flex"><input class="form-control me-2" type="search" placeholder="输入你的关键词" aria-label="Search"><button class="btn btn-outline-success" type="submit">站内搜索</button></form></div></div>
</nav><div class="bs-docs-header" id="content" tabindex="-1"><div class="container"><h1> 联系michael </h1><div class="lead"><address>电子邮件:<strong>michael@xxx.com</strong><br>地址:地球村86号<br>邮政编码:<strong>xxxxxx</strong><br><abbr title="Phone">联系电话:</abbr> 1234567890</address></div></div>
</div></body>
</html>

在这里插入图片描述

创建 web_server.py

实现客户端和服务器的 HTTP 通信

注:由于 HTML 里面写了很多下载的 css 文件地址,路径总是报错,最后还是 建议引用 CDN 写法,相关库地址查询https://www.bootcdn.cn/

<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.0.2/css/bootstrap.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/popper.js/2.9.2/cjs/popper-base.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.0.2/js/bootstrap.js"></script>
import socket
import re
from multiprocessing import Process  # 多线程HTML_ROOT_DIR = './'  # 设置静态页面的根目录class HTTPServer:def __init__(self):self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)def start(self):self.server_socket.listen(128)  # 最大连接数128print("服务器等待客户端连接...")while True:client_socket, client_addr = self.server_socket.accept()  # 建立客户端连接print("[%s, %s]用户连接上了" % client_addr)handle_client_process = Process(target=self.handle_client, args=(client_socket,))# 实例化线程,第一个参数调用函数 ,第二个参数 传递给前者的参数,元组形式handle_client_process.start()  # 开启线程client_socket.close()  # 关闭客户端socketdef handle_client(self, client_socket):# 处理客户端请求request_data = client_socket.recv(1024)  # 接收客户端请求print("request data:", request_data)request_lines = request_data.splitlines()  # 按行分割for line in request_lines:print(line)  # 输出信息request_start_line = request_lines[0]  # 获取请求报文print("*" * 10)print(request_start_line.decode("utf-8"))file_name = re.match(r"\w+ +(/[^ ]*) ", request_start_line.decode("utf-8")).group(1)# 使用正则表达式,提取请求的文件名,group(1) 列出第一个括号匹配部分if file_name == "/":file_name = "/simple_navbar.html"try:# 尝试打开文件file = open(HTML_ROOT_DIR + file_name, "rb")except IOError:# 读取文件失败,返回404response_start_line = "HTTP/1.1 404 Not Found\r\n"response_headers = "Server: Michael server\r\n"response_body = "The file %s is not found! please check again!" % (HTML_ROOT_DIR + file_name)else:file_data = file.read()file.close()# 构造响应数据response_start_line = "HTTP/1.1 200 OK\r\n"response_headers = "Server: Michael server\r\n"response_body = file_data.decode("utf-8")# 拼接返回数据response = response_start_line + response_headers + "\r\n" + response_bodyprint("response data:", response)client_socket.send(bytes(response, "utf-8"))  # 向客户端发送响应数据client_socket.close()  # 关闭客户端连接def bind(self, port):self.server_socket.bind(("127.0.0.1", port))def main():http_server = HTTPServer()http_server.bind(8000)http_server.start()if __name__ == "__main__":main()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4. WSGI 接口

上面实现了一个静态服务器,但是现在很少使用,更多的是使用 动态页面,实现交互性

  • 例如,注册登录网站,用户输入数据,web服务器不处理用户数据(不是它的职责),CGI 诞生

4.1 CGI 通用网关接口

  • Common Gateway Interface 是一段程序,运行在服务器上
  • web 服务器将请求发送给 CGI 应用程序,再将 CGI 动态生成的 HTML 页面发送回客户端

CGI 局限性:创建完解释器进程,用完就抛弃,大量的请求导致服务器停机

  • CGI 加强版 FastCGI 出现,其使用 进程/线程池 来处理一连串的请求
    减少了 网页服务器CGI 程序之间 交互的开销

4.2 WSGI

  • FastCGI 标准下写异步的 Web 服务不太方便,WSGI (Web Server Gateway Interface 服务器网关接口) 出现

下图 from https://www.cnblogs.com/wilber2013/p/4763067.html
在这里插入图片描述

4.3 定义 WSGI 接口

最简单的web版本 hello world

def applications(environ, start_response):start_response('200 OK', [('Content-Type', 'text/html')])return [b'<h1>Hello, Michael!</h1>']

上面函数就是符合 WSGI 标准的一个 HTTP 处理函数

  • environ :一个所有 HTTP 请求信息的字典对象
  • start_response:一个发送 HTTP 响应的函数

好处:web 解析 和 应用程序逻辑 分离,可以各自做自己擅长的事

python 内置了 WSGI:wsgiref 模块(它没有考虑运行效率,仅供开发测试)

4.4 运行 WSGI 服务

  • wsgi_app.py
# wsgi 应用程序
def app(environ, start_response):# 响应信息start_response('200 OK', [('Content-Type', 'text/html')])file_name = environ['PATH_INFO'][1:] or 'simple_navbar.html'HTML_ROOT_DIR = './'try:# 打开文件file = open(HTML_ROOT_DIR + file_name, 'rb')except IOError:# 响应异常response_body = "{} not found".format(HTML_ROOT_DIR + file_name)else:# 读取文件file_data = file.read()file.close()# 构造响应数据response_body = file_data.decode('utf-8')return [response_body.encode('utf-8')]  # 返回数据
  • wsgi_server.py
# WSGI 服务器
from wsgiref.simple_server import make_server
from wsgi_app import app# 创建一个服务器,IP地址为空,端口号为8000,处理函数是app
httpd = make_server('', 8000, app)
print('Serving HTTP on port 8000...')
httpd.serve_forever()  # 开始监听HTTP请求

运行 wsgi_server.py ,在浏览器输入 http://127.0.0.1:8000/ 就可以访问网页了

在这里插入图片描述

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

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

相关文章

android 75 新闻列表页面

new.xml <?xml version"1.0" encoding"UTF-8" ?> <newslist><news><title>黑马52期就业快报</title><detail>热烈祝贺黑马52期平均薪水突破13k</detail><comment>15687</comment><image>ht…

python web开发 MySQL数据库基础

文章目录1. 简介2. 下载安装3. 操作 MysQL 数据库3.1 创建数据库3.2 选择数据库3.3 查看数据库3.4 删除数据库4. 数据类型5. 操作 MysQL 数据表5.1 创建数据表5.2 查看表的结构5.3 修改表的结构5.4 删除数据表6. 操作 MySQL 数据表记录6.1 添加数据6.2 查询、修改、删除learnin…

python 操作MySQL数据库

文章目录1. 安装 PyMySQL2. 连接对象3. 游标对象4. 增删改操作cursor.execute(sql)cursor.executemany(sql, seq_of_params)5. 查询操作6. ORM编程常用 python ORM 库learning from 《python web开发从入门到精通》 1. 安装 PyMySQL conda 虚拟环境下安装 pip install pymysq…

python web框架基础

文章目录1. Web框架简介1.1 MVC1.2 模板引擎2. 常用 Python Web 框架3. 虚拟环境4. 部署方式learning from 《python web开发从入门到精通》 1. Web框架简介 简化 web 开发的软件框架 一般都支持&#xff1a;管理路由&#xff0c;支持数据库&#xff0c;MVC&#xff0c;ORM&…

导Excel数据到Oracle的脚本,Oracle使用TOAD实现导入导出Excel数据

在Oracle应用程序的开发过程中&#xff0c;访问数据库对象和编写SQL程序是一件乏味且耗费时间的工作&#xff0c;对数据库进行日常管理也是需要很多SQL脚本才能完成的。Quest Software为此提供了高效的Oracle应用开发工具-Toad。在Toad的新版本中&#xff0c;还加入了DBA模块&a…

Chapter 14 Exercises Problems

转载于:https://www.cnblogs.com/momoko/p/4937730.html

FastAPI 结合 SQLAlchemy 操作 MySQL 数据库

文章目录1. 安装 SQLAlchemy2. 创建数据库3. SQLAlchemy 连接 MySQL4. 创建数据模型5. 创建 Pydantic 模型6. crud 工具7. main函数learning from 《python web开发从入门到精通》 1. 安装 SQLAlchemy pip install sqlalchemy 2. 创建数据库 mysql -u root -p 命令行登录 M…

LeetCode 2094. 找出 3 位偶数

文章目录1. 题目2. 解题1. 题目 给你一个整数数组 digits &#xff0c;其中每个元素是一个数字&#xff08;0 - 9&#xff09;。数组中可能存在重复元素。 你需要找出 所有 满足下述条件且 互不相同 的整数&#xff1a; 该整数由 digits 中的三个元素按 任意 顺序 依次连接 …

LeetCode 2095. 删除链表的中间节点(快慢指针)

文章目录1. 题目2. 解题1. 题目 给你一个链表的头节点 head 。删除 链表的 中间节点 &#xff0c;并返回修改后的链表的头节点 head 。 长度为 n 链表的中间节点是从头数起第 ⌊n / 2⌋ 个节点&#xff08;下标从 0 开始&#xff09;&#xff0c;其中 ⌊x⌋ 表示小于或等于 x…

LeetCode 2096. 从二叉树一个节点到另一个节点每一步的方向(最小公共祖先)

文章目录1. 题目2. 解题1. 题目 给你一棵 二叉树 的根节点 root &#xff0c;这棵二叉树总共有 n 个节点。 每个节点的值为 1 到 n 中的一个整数&#xff0c;且互不相同。 给你一个整数 startValue &#xff0c;表示起点节点 s 的值&#xff0c;和另一个不同的整数 destValue …

LeetCode 2097. 合法重新排列数对(欧拉路径)

文章目录1. 题目2. 解题1. 题目 给你一个下标从 0 开始的二维整数数组 pairs &#xff0c;其中 pairs[i] [starti, endi] 。如果 pairs 的一个重新排列&#xff0c;满足对每一个下标 i &#xff08; 1 < i < pairs.length &#xff09;都有 endi-1 starti &#xff0c…

《如何在大学里脱颖而出(How to Win at College)》读书笔记

《如何在大学里脱颖而出(How to Win at College)》读书笔记 图书简介 中文版&#xff1a; 英文版&#xff1a; 作者卡尔纽波特&#xff08;Cal Newport&#xff09;于 2004 年6月以优等生荣誉学会会员身份毕业于达特茅斯学院。曾在《华尔街日报》的学报和《今日商务》等杂志上发…

LeetCode 2099. 找到和最大的长度为 K 的子序列

文章目录1. 题目2. 解题1. 题目 给你一个整数数组 nums 和一个整数 k 。 你需要找到 nums 中长度为 k 的 子序列 &#xff0c;且这个子序列的 和最大 。 请你返回 任意 一个长度为 k 的整数子序列。 子序列 定义为从一个数组里删除一些元素后&#xff0c;不改变剩下元素的顺…

cms安装教程Linux,DoraCMS安装教程(linux)

最近在熟悉linux环境&#xff0c;也基本上把DoraCMS部署上去了&#xff0c;本教程基于ubuntu server 14.0.4&#xff0c;其它linux版本部署方式基本上差不多&#xff0c;下面详细说明一下&#xff1a;1、进入server环境下&#xff0c;在ubuntu目录下建立文件夹softbak,我们用来…

LeetCode 2100. 适合种地的日子(计数)

文章目录1. 题目2. 解题1. 题目 你和一群强盗准备种地。给你一个下标从 0 开始的整数数组 security &#xff0c;其中 security[i] 是第 i 天 天气热的数量。日子从 0 开始编号。同时给你一个整数 time 。 如果第 i 天满足以下所有条件&#xff0c;我们称它为一个适合种地的日…

如何在linux中使用u盘,如何在Linux系统下使用U盘

如何在Linux系统下使用U盘Linux系统中U盘被视为SCSI设备, SCSI设备对应的设备文件格式为“sdX” 系统中的第一个SCSI设备表示“sda”&#xff0c;第二个表示为“sdb”等。下面是jy135小编收集整理的U盘里面的.如何在Linux系统下使用U盘&#xff0c;欢迎阅读。在Linux系统下&…

linux sys存放内容,了解linux系统目录,sys,tmp,usr,var!

原标题&#xff1a;了解linux系统目录&#xff0c;sys,tmp,usr,var&#xff01;linux小白到大神的成长之路&#xff1a;了解linux系统目录&#xff0c;sys,tmp,usr,var&#xff01;本经验由宗龙龙原创,全文共600多字&#xff0c;阅读需要14分钟&#xff0c;如果文中存在错误&am…

LeetCode 2101. 引爆最多的炸弹(图的遍历)

文章目录1. 题目2. 解题1. 题目 给你一个炸弹列表。一个炸弹的 爆炸范围 定义为以炸弹为圆心的一个圆。 炸弹用一个下标从 0 开始的二维整数数组 bombs 表示&#xff0c;其中 bombs[i] [xi, yi, ri] 。xi 和 yi 表示第 i 个炸弹的 X 和 Y 坐标&#xff0c;ri 表示爆炸范围的…

vim学习笔记(3)眼花缭乱的Vim模式

vim的模式问题&#xff0c;网上说的比较乱&#xff0c;我仔细的查了一下资料&#xff0c;并在这里做一个总结。 总的来说是六大种模式&#xff0c;分别是&#xff1a; 普通(Normal) 可视(Visual) 选择(Select) 插入(Insert) 命令行(Command-line) Ex模式。 还有六个小的组合模式…

linux脚本大全,shell大全

命令解析器——例如bash是一个程序&#xff0c;可以解析shell命令shell基本语法变量环境变量敲命令“env”可以取出所有环境变量环境变量可以当全局变量来使用set命令可以输出当前系统的全部环境变量以及函数unset命令用于删除一个环境变量本地变量自定义的变量——局限在某个脚…