HTTP协议和静态Web服务器

3.4.1 HTTP协议

1.HTTP协议介绍

  • 全程:超文本传输协议
  • 作用:规定浏览器和web服务器通信的数据格式
  • HTTP协议是在应用层的协议,基于传输层的TCP传输协议,设计之初

是传输网页数据,现在可以传输任何数据。

浏览器访问web服务器的通信过程

2.URL

1.url概念

​ 意思是统一资源定位符,通俗理解就是网络资源地址

2.组成

  • 协议部分:http://, https://, ftp://, sftp://, smb://等
  • 域名部分:www.baidu.com
  • 资源路径部分:/res/xxxxx191xxx
  • 查询参数部分: ?page=1&count=20

3.4.2 查看HTTP协议的通信过程

1.带开发者工具模式的浏览器

一般有火狐谷歌,这里我们使用谷歌浏览器来查看HTTP协议的通信过程

开发者工具的标签选项说明:

  • 元素(Elements):用于查看或修改HTML标签
  • 控制台(Console):执行js代码
  • 源代码(Sources):查看静态资源文件,断点调试JS代码
  • 网络(Network):查看http协议的通信过程

开发者工具的使用说明:

  1. 点击Network标签选项
  2. 在浏览器的地址栏输入百度的网址,就能看到请求百度首页的http的通信过程
  3. 这里的每项记录都是请求+响应的一次过程
  4. 如果返回的是个html文件那大概率是不止要一次请求,在执行代码的过程中会慢慢要多次请求

2.查看HTTP协议通信的过程

查看HTTP请求信息图

查看HTTP响应信息的图

3.HTTP请求报文

HTTP最常见的请求报文有2种:

  • GET方式:获取web服务器数据
  • POST方式:向web服务器提交数据

1. HTTP GET请求报文分析

组成

  1. 请求行:GET / HTTP/1.1\r\n

    1. 请求方式:GET
    2. 请求资源路径:/
    3. 协议版本:HTTP/1.1
    4. \r\n:回车换行
  2. 请求头 格式(属性名:属性值\r\n)

    1. Host:主机地址和端口 默认是80

    2. Connection:keep-alive 保持长连接

      拓展

      长连接和短连接各有优势

      长连接操作间隔的速度快,但是需要大量系统资源

      短连接速度慢,但是需求的系统资源少

    3. Upgrade-Insecure-Requests: 1 # 让浏览器升级不安全请求,使用https请求

    4. User-Agent:浏览器访问标志,不同浏览器和平台有不同的标志

    5. Accept:可接受的文件格式

    6. Accept-Encoding:可接受的压缩格式

    7. Accept-language:可接受的语言

    8. Cookie:登录用户的身份标志

  3. 空行 \r\n

2. HTTP POST请求报文分析

组成

  1. 请求行:

    1. 请求方式:POST
    2. 请求资源路径:一般是需要登录或者输入查询的地方
    3. 协议版本:
    4. \r\n:回车换行
  2. 请求头: 属性名:属性值\r\n
  3. 空行:\r\n
  4. 请求体:需要提交给web服务器的数据 (不用带\r\n)

注意

请求体可以为空,但是一般为空我们就用GET

4.HTTP响应报文

1.响应报文组成

  1. 响应行 :HTTP/1.1 200 OK \r\n

    1. 协议版本:HTTP/1.1 (和请求报文区别,先报协议版本后出状态)
    2. 状态码:200
    3. 状态描述:0k
    4. 回车换行:\r\n
  2. 响应头 属性名:属性值 \r\n
    1. Server: 服务器名称
    2. Content-Type:text/html; charset=utf-8 内容类型
    3. Transfer-Encoding:chunked # 发送给客户端内容不确定内容长度,发送结束的标记是0\r\n, Content-Length表示服务端确定发送给客户端的内容大小,但是二者只能用其一。
    4. Connection:keep-alive 和客户端保持长连接
    5. Date:Fri, 23 Nov 2018 02:01:05 GMT 服务器的响应时间
  3. 空行
  4. 响应体 响应给客户端的数据

2.响应状态码

状态码 说明
200 请求成功
307 重定向
400 错误的请求,请求地址或者参数有误
404 请求资源在服务器不存在
500 服务器内部源代码出现错误

3.4.3 搭建Python自带的静态Web服务器

1.静态Web服务器

可以为发出请求的浏览器提供静态文档的程序

一般为动态的服务器,我们做的是数据不变化的静态资源

2.搭建Web服务器

在已配置的static文件夹里打开终端,利用Python自带的静态web服务器发起

python3 -m http.server 9000[端口号 可选]
Serving HTTP on 0.0.0.0 port 9000 (http://0.0.0.0:9000/) ...
192.168.19.69 - - [22/Nov/2020 08:41:55] "GET / HTTP/1.1" 200 -
192.168.19.69 - - [22/Nov/2020 08:41:55] "GET /favicon.ico HTTP/1.1" 200 -
192.168.19.69 - - [22/Nov/2020 08:42:32] "GET /index.html HTTP/1.1" 200 -
192.168.19.69 - - [22/Nov/2020 08:42:38] "GET /index2.html HTTP/1.1" 200 -
192.168.19.69 - - [22/Nov/2020 08:42:38] "GET /web.jpg HTTP/1.1" 200 -
192.168.19.69 - - [22/Nov/2020 08:42:51] "GET /grand.html HTTP/1.1" 200 -
192.168.19.69 - - [22/Nov/2020 08:42:51] "GET /images/001.jpg HTTP/1.1" 200 -
192.168.19.69 - - [22/Nov/2020 08:42:51] "GET /js/jquery-1.12.4.min.js HTTP/1.1" 200 -
192.168.19.69 - - [22/Nov/2020 08:42:51] "GET /images/002.jpg HTTP/1.1" 200 -
192.168.19.69 - - [22/Nov/2020 08:42:51] "GET /images/003.jpg HTTP/1.1" 200 -
192.168.19.69 - - [22/Nov/2020 08:42:51] "GET /images/004.jpg HTTP/1.1" 200 -
192.168.19.69 - - [22/Nov/2020 08:42:51] "GET /images/005.jpg HTTP/1.1" 200 -
192.168.19.69 - - [22/Nov/2020 08:43:03] "GET /grand.html HTTP/1.1" 200 -
192.168.19.69 - - [22/Nov/2020 08:43:03] "GET /favicon.ico HTTP/1.1" 200

3.开发一个返回固定页面的静态web服务器

实现步骤:

  1. 编写一个TCP服务端程序
  2. 获取浏览器发送的http请求报文数据
  3. 读取固定页面数据,把页面数据组装成HTTP响应报文数据发送给浏览器。
  4. HTTP响应报文数据发送完成以后,关闭服务于客户端的套接字。
import socket# HTTP是基于TCP传输协议的服务器,我们从昨天的TCP服务器端创建开始
if __name__ == '__main__':tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)tcp_server_socket.bind(('', 9222))tcp_server_socket.listen(128)# 以上是搭建了一个本地tcp服务器端,一旦有用户创立连接我们再做下一步new_socket, ip_port = tcp_server_socket.accept()while True:# 我们先读取一下浏览器发过来的请求报头但是不做解析,默认读取是4k字节client_data = new_socket.recv(4096)# 解码一下并且打出请求报头client_content = client_data.decode('utf-8')print(client_content)# 我们读取一下配置好的文档,来自定义一个静态文档,然后按照HTTP协议的响应报文格式返回# 自定义一个静态文档内容读取with open('static/index.html', 'rb')as f:ret = f.read()# 定义一个响应行response_line = 'HTTP/1.1 200 OK\r\n'# 定义一个响应头response_header = 'Server: PWS1.0\r\n'# 定义一个响应体 也就是我们写好的网页文件response_body = ret# 把所有响应格式,按照HTTP协议的格式打包发送response_data = (response_line+response_header+'\r\n').encode('utf-8')+response_bodynew_socket.send(response_data)new_socket.close()# 我们结束通讯是因为我们设计的服务器十分简陋,建立tcp连接的时候也没有具体互相告诉对面即将发送的数据大小,数据头尾,实际上浏览器是不知道我们具体发多少的,如果没有我们关闭连接,浏览器会处于长时间接受响应报文的状态

我们尝试访问一下本地页面

GET /favicon.ico HTTP/1.1
Host: 127.0.0.1:9222
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.193 Safari/537.36 Edg/86.0.622.68
Accept: image/webp,image/apng,image/*,*/*;q=0.8
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: no-cors
Sec-Fetch-Dest: image
Referer: http://127.0.0.1:9222/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6,zh-TW;q=0.5

可以看到终端完整的打出了

4.开发一个返回指定页面数据的静态web服务器

实现步骤:

  1. 编写一个TCP服务端程序
  2. 获取浏览器发送的http请求报文数据
  3. 读取固定页面数据,把页面数据组装成HTTP响应报文数据发送给浏览器。
  4. HTTP响应报文数据发送完成以后,关闭服务于客户端的套接字。
import socket# 之前我们只能返回一个指定页面,而且对用户发过来的请求报头不解析
# HTTP是基于TCP传输协议的服务器,我们从昨天的TCP服务器端创建开始
def main():tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)tcp_server_socket.bind(('', 9222))tcp_server_socket.listen(128)# 以上是搭建了一个本地tcp服务器端,一旦有用户创立连接我们再做下一步while True:new_socket, ip_port = tcp_server_socket.accept()client_request_data = new_socket.recv(4096)if not client_request_data:print("用户关闭了浏览器")new_socket.close()return# 解码一下并且打出请求报头client_content = client_request_data.decode('utf-8')print(client_content)# 限定指定字符串进行分割,最大分割次数2request_list = client_content.split(" ", maxsplit=2)# 取出访问路径request_path = request_list[1]print(request_path)# 如果访问路径为/则为首页if request_path == "/":request_path = '/index.html'# 对截取的用户资源路径进行判断,进行读取,如果发生错误则返回错误的页面try:with open("static"+request_path, "rb")as f:file_data = f.read()except Exception as e:print("用户访问出错", e)with open("static/error.html", 'rb')as ef:file_data = ef.read()# 定义一个错误的响应行response_line = 'HTTP/1.1 404 Not Found\r\n'# 定义一个响应头response_header = 'Server: PWS1.0\r\n'# 定义一个响应体 也就是我们写好的网页文件response_body = file_dataresponse_data = (response_line + response_header + '\r\n').encode('utf-8') + response_bodynew_socket.send(response_data)# 如果没有发生错误,则正确读取else:# 定义一个响应行response_line = 'HTTP/1.1 200 OK\r\n'# 定义一个响应头response_header = 'Server: PWS1.0\r\n'# 定义一个响应体 也就是我们写好的网页文件response_body = file_data# 把所有响应格式,按照HTTP协议的格式打包发送response_data = (response_line + response_header + '\r\n').encode('utf-8') + response_bodynew_socket.send(response_data)finally:new_socket.close()if __name__ == '__main__':main()

5.开发一个多任务和函数封装版的静态web服务器

流程步骤

  • 给每个连接创建一个子进程,由子进程处理连接客户端的请求
  • 把创建的子客户端设置成守护进程
import socket
import threading# 之前我们只能返回一个指定页面,而且对用户发过来的请求报头不解析
# HTTP是基于TCP传输协议的服务器,我们从昨天的TCP服务器端创建开始
def main():tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)tcp_server_socket.bind(('', 9222))tcp_server_socket.listen(128)# 以上是搭建了一个本地tcp服务器端,一旦有用户创立连接我们再做下一步while True:new_socket, ip_port = tcp_server_socket.accept()new_thread = threading.Thread(target=client_request, args=(new_socket, ip_port))new_thread.setDaemon(True)new_thread.start()def client_request(new_socket, ip_port):print("有一位新用户接入,他的ip地址为", ip_port)client_request_data = new_socket.recv(4096)if not client_request_data:print("用户关闭了浏览器")new_socket.close()return# 解码一下并且打出请求报头client_content = client_request_data.decode('utf-8')# print(client_content)# 限定指定字符串进行分割,最大分割次数2request_list = client_content.split(" ", maxsplit=2)# 取出访问路径request_path = request_list[1]print("该用户访问的路径为", request_path)# 如果访问路径为/则为首页if request_path == "/":request_path = '/index.html'# 对截取的用户资源路径进行判断,进行读取,如果发生错误则返回错误的页面try:with open("static" + request_path, "rb")as f:file_data = f.read()except Exception as e:print("用户访问出错", e)with open("static/error.html", 'rb')as ef:file_data = ef.read()# 定义一个错误的响应行response_line = 'HTTP/1.1 404 Not Found\r\n'# 定义一个响应头response_header = 'Server: PWS1.0\r\n'# 定义一个响应体 也就是我们写好的网页文件response_body = file_dataresponse_data = (response_line + response_header + '\r\n').encode('utf-8') + response_bodynew_socket.send(response_data)# 如果没有发生错误,则正确读取else:# 定义一个响应行response_line = 'HTTP/1.1 200 OK\r\n'# 定义一个响应头response_header = 'Server: PWS1.0\r\n'# 定义一个响应体 也就是我们写好的网页文件response_body = file_data# 把所有响应格式,按照HTTP协议的格式打包发送response_data = (response_line + response_header + '\r\n').encode('utf-8') + response_bodynew_socket.send(response_data)finally:new_socket.close()if __name__ == '__main__':main()

6.做一个面向对象版的封装静态web服务器

实现步骤:

  1. 把提供服务的Web服务器抽象成一个类(HTTPWebServer)
  2. 提供Web服务器的初始化方法,在初始化方法里面创建socket对象
  3. 提供一个开启Web服务器的方法,让Web服务器处理客户端请求操作。
import socket
import threading# 先分析需求,我们需要创立的是一个服务器类
# 首先我们服务器需要的属性有几样 1.socket 2.端口绑定 3.监听数
class WebHttpServer(object):def __init__(self):# 实例属性最需要的就是服务器嵌套的socketself.web_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)# 同时需要设定它的端口复用self.web_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)self.web_socket.bind(("", 9222))self.web_socket.listen(128)# 服务器属性创立好后还需要能处理客户端的需求,可以直接照搬我们前面做的函数# 但是可以看到如果作为实例方法我们需要传参实例,但是我们并不需要传任何实例对象和属性进去,因为不需求这个方法返回任何值,因此我们将其做成静态方法@staticmethoddef client_request(new_socket, ip_port):print("有一位新用户接入,他的ip地址为", ip_port)client_request_data = new_socket.recv(4096)if not client_request_data:print("用户关闭了浏览器")new_socket.close()return# 解码一下并且打出请求报头client_content = client_request_data.decode('utf-8')# print(client_content)# 限定指定字符串进行分割,最大分割次数2request_list = client_content.split(" ", maxsplit=2)# 取出访问路径request_path = request_list[1]print("该用户访问的路径为", request_path)# 如果访问路径为/则为首页if request_path == "/":request_path = '/index.html'# 对截取的用户资源路径进行判断,进行读取,如果发生错误则返回错误的页面try:with open("static" + request_path, "rb")as f:file_data = f.read()except Exception as e:print("用户访问出错", e)with open("static/error.html", 'rb')as ef:file_data = ef.read()# 定义一个错误的响应行response_line = 'HTTP/1.1 404 Not Found\r\n'# 定义一个响应头response_header = 'Server: PWS1.0\r\n'# 定义一个响应体 也就是我们写好的网页文件response_body = file_dataresponse_data = (response_line + response_header + '\r\n').encode('utf-8') + response_bodynew_socket.send(response_data)# 如果没有发生错误,则正确读取else:# 定义一个响应行response_line = 'HTTP/1.1 200 OK\r\n'# 定义一个响应头response_header = 'Server: PWS1.0\r\n'# 定义一个响应体 也就是我们写好的网页文件response_body = file_data# 把所有响应格式,按照HTTP协议的格式打包发送response_data = (response_line + response_header + '\r\n').encode('utf-8') + response_bodynew_socket.send(response_data)finally:new_socket.close()# 既然已经有了属性和处理客户端请求的方法,那我们必须还有个方法,就是启动实例,这里把之前启动的多线程方法加进去def start(self):while True:new_socket, ip_port = self.web_socket.accept()# 创建线程使用的是静态方法new_thread = threading.Thread(target=self.client_request, args=(new_socket, ip_port))new_thread.setDaemon(True)new_thread.start()def main():web_server = WebHttpServer()web_server.start()if __name__ == '__main__':main()

7.用命令行启动并且动态绑定端口的静态web服务器

我们就算封装了服务器,但是实际上也只能实例化一个对象并且端口是事先设定的,我们为了通用化,一般是使用命令行操作运行,或者图形化的界面启动,明显我们之前封装的类还得更改一下。

Python基础 3.4 HTTP协议和静态Web服务器相关推荐

  1. Python 高级:05 HTTP 协议和静态 Web 服务器

    一.HTTP 协议 1. HTTP 协议的介绍 HTTP 协议的全称是(Hyper Text Transfer Protocol),翻译过来就是超文本传输协议.超文本就是超级文本的缩写,是指超越文本限 ...

  2. 〖Web全栈开发③〗—HTTP协议和静态web服务器

    HTTP协议和静态web服务器 (一)三次握手和四次挥手 (二)HTTP协议 2.1 HTTP协议的定义 2.2 HTTP协议的组成 (三)搭建python自带静态web服务器 3.1 静态web服务 ...

  3. 搭建Python自带静态Web服务器

    学习目标 能够知道搭建Python自带Web服务器 1. 静态Web服务器是什么? 可以为发出请求的浏览器提供静态文档的程序. 平时我们浏览百度新闻数据的时候,每天的新闻数据都会发生变化,那访问的这个 ...

  4. Python搭建静态web服务器

    核心还是使用Python的socket实现的,socket的具体用法前面文章有写,这里不写太多注释. 1.本地搭建python静态web服务器 在资源目录打开命令终端,输入命令:python -m h ...

  5. python实现web服务器_python实现静态web服务器

    HTTP协议简介 HTTP请求 1:浏览器首先向服务器发送HTTP请求,请求包括: 方法:GET还是POST,GET仅请求资源,POST会附带用户数据: 路径:/full/url/path: 域名:由 ...

  6. 【HTTP协议其实很简单】03.自己写一个微型静态Web服务器

    自己做一个微型静态Web服务器 这一篇简单粗暴一点,先上干货,看代码注释 JDK版本:1.8 实现自定义错误页.404页. package com.hawkon;import java.io.*; i ...

  7. python多任务、面向对象、命令行启动动态绑定端口号静态web服务器代码实现

    一.静态web服务器-多任务 多任务web服务器:使用多线程,比进程更节省资源,支持多用户同时访问,可以同时处理多个客户端请求 实现步骤 若客户端与服务端建立连接,则创建子线程,使用子线程处理客户端请 ...

  8. python自带静态web服务器搭建代码实现(一)

    一.静态web服务器 静态web法服务器:可为发出请求的浏览器提供静态文档的程序,平时上网浏览的页面都是动态的,而开发的是静态的,页面数据不会发生变化 搭建python自带的静态web服务器 命令:p ...

  9. node 创建静态web服务器(下)(处理异步获取数据的两种方式)

    接上一章. 上一章我们说创建的静态web服务器只能识别html,css,js文件,功能较为单一,且图片格式为text/html,这是不合理的. 本章,我们将解决该问题. 这里,我们先准备好一个json ...

最新文章

  1. Android中Messenger进程间通信
  2. 协作工具 discord 和 slack
  3. 实验研究信标无线电能输出功率的因素
  4. 方差分析中怎么看有无显著性影响_用R语言做单因素方差分析及多重比较
  5. noip2006提高组-金明的预算方案解题报告
  6. 汉字的动态编码与显示方案
  7. 配置使用rsyslog+loganalyzer收集防火墙及交换机日志
  8. Arcgis javascript那些事儿(十七)——地理编码服务的发布与使用
  9. 步进电机驱动实验(89C51 + KEIL + Proteus)
  10. 怎么使用biopython_Biopython - 简介
  11. NMF非负矩阵分解算法(Non-negative Matrix Factorization)
  12. SS导航菜单水平居中的多种方法
  13. vue项目项目启动步骤及常见错误处理
  14. c语言入门自学ppt,c语言基础知识ppt
  15. SugarCRM将告诉你什么是客户关系管理系统中最成功解决方案
  16. C++桌面小精灵:实现像Office助手一样的帮助精灵
  17. 计算机拓展训练论文,素质拓展训练论文拓展训练论文
  18. LeetCode:1287. Element Appearing More Than 25% In Sorted Array - Python
  19. MERGER INTO语法
  20. AD中PCB布局与布线的一般原则

热门文章

  1. Barra模型学习笔记-1
  2. CF 242E XOR on Segment 【线段树】
  3. [LINUX]sed查找不包含某个字符串的行,并进行替换
  4. CCS Cannot open soure file ***
  5. 火影忍者ol手游今天未能连接服务器,火影忍者ol游戏上不去怎么办_火影忍者ol登录/安装失败解决方法...
  6. C4D R26 渲染学习笔记 建模篇(1):参数模型
  7. C++游戏辅助开发实战x64游戏逆向汇编封包游戏安全攻防反调试
  8. 学习游戏原画必看的13个知识点「收藏起来慢慢看!」
  9. 解决MATLAB遇到内部问题,需要关闭
  10. java使用openOffice 实现word转pdf