文章目录
HTTP 简介
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写;
是用于万维网(WWW:World Wide Web)服务器与本地浏览器之间传输超文本的传送协议;
HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。
它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展。
HTTP协议工作于客户端-服务端架构为上。
浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。
Web服务器根据接收到的请求后,向客户端发送响应信息。
HTTP 协议特性
基于TCP/P协议
- HTTP协议是基于TCP/IP协议之上的应用层协议。
基于请求-响应模式
- HTTP协议规定,请求从客户端发出,最后服务器端响应该请求并返回。
- 换句话说,肯定是先从客户端开始建立通信的,服务器端在没有接收到请求之前不会发送响应。
无状态保存
- HTTP是一种不保存状态,即无状态(stateless)协议;
- HTTP协议自身不对请求和响应之间的通信状态进行保存,也就是说在HTTP这个级别协议对于发送过的请求或响应都不做持久化处理;
- 使用HTTP协议,每当有新的请求发送时,就会有对应的新响应产生;
- 协议本身并不保留之前一切的请求或响应报文的信息;
- 这是为了更快地处理大量事务,确保协议的可伸缩性,而特意把HTTP协议设计成如此简单的。
短连接
- HTTP1.0默认使用的是短连接,浏览器和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。
- HTTP/1.1起,默认使用长连接。要使用长连接,客户端和服务器的HTTP首部的Connection都要设置为keep-alive,才能支持长连接。
- HTTP长连接,指的是复用TCP连接。多个HTTP请求可以复用同一个TCP连接,这就节省了TCP逐接建立和断开的消耗。
HTTP请求协议与响应协议
假设存在两个应用:应用A、应用B;应用A要给应用B发送消息,如Hello World;
发送端(应用A)流程如下:
- 应用层:应用A首先准备好要发送的数据(如“Hello World”)和目的地址(即应用B的地址)。
- 传输层:应用A将数据交给传输层,选择使用UDP或TCP协议。传输层会为数据添加端口号等信息,并创建数据段(对于TCP)或用户数据报(对于UDP)。
- 网络层:传输层将数据段或用户数据报交给网络层,网络层使用IP协议来进一步封装数据,添加源IP地址和目的IP地址,并选择适当的路由路径。
- 数据链路层:数据到达数据链路层后,通常会被封装成帧,添加源MAC地址和目的MAC地址,这通常是通过ARP协议完成的,用于将目的IP地址解析为相应的MAC地址。然后,帧在局域网内通过以太网等协议进行传输。
- 物理层:最后,数据到达物理层,物理层将帧转换为比特流,并将这些比特流转换为电信号或光信号,通过物理介质(如网络电缆或光纤)发送到目的地。
接收端(应用B)流程是反向的,流程如下:
- 物理层:应用B的物理层接收到信号,并将其转换回比特流;
- 数据链路层:数据链路层解封装接收到的帧,验证MAC地址,并将数据上传到网络层;
- 网络层:网络层解封装数据,根据IP地址进行路由,并将数据上传到传输层;
- 传输层:传输层解封装数据,验证端口号,并将数据交给应用层;
- 应用层:最终,应用B的应用程序接收到数据,并处理或显示接收到的消息(如“Hello World”);
这个流程涵盖了从应用层到物理层,再到接收端相应层次的完整通信过程;
在这个过程中,大多数网络层次的细节和协议(如IP、ARP、以太网等)都是由操作系统和网络库自动处理的,应用开发者通常不需要直接参与。
请求和响应协议流程图
请求和响应协议总结
- HTTP协议包含由浏览器发送数据到服务器需要遵循的请求协议与服务器发送数据到浏览器需要遵循的请求协议。
- 用于HTTP协议交互的信息被称为HTTP报文;
- 请求端(客户端)的HTTP报文叫做请求报文;
- 响应端(服务器端)的HTTP报文叫做响应报文;
- HTTP报文本身是由多行数据构成的字文本。
URL的组成
一个完整的URL包括:协议、ip、端口、路径、参数
例如:https://www.baidu.com/s?wd=hello
- **协议:**https
- **IP:**www.baidu.com
- **端口:**默认是80,
- 路径:/s
- **参数:**wd=hello
Content-Type
Content-Type的概念:
- Content-Type是HTTP协议header中的一个重要参数;
- 它用于表示发送或者接收到的数据类型,浏览器会根据Content-Type来决定数据的打开方式;
- Content-Type描述的是发送端,这里发送端既可以是服务器也可以是客户端
Content-Type可以指定的数据类型如下:
- application/json 。适用于提交复杂结构的JSON数据,常见于Restful风格的服务端接口。
- text/html 。通常与Web页面相关,用于指示服务器返回的HTML内容。
- text/xml 。主要用于SOAP和RESTful API之间的数据交换,以及XML文件的处理。
- image/jpeg、image/png等图像格式 。用于发送和接收图像文件。
- audio/mpeg、video/mp4等音频视频格式 。用于发送和接收音频视频文件。
- multipart/form-data 。用于包含表单数据的请求,如上传文件。
常见的请求头字段
下面是一个常见的HTTP请求头信息
GET /home.html HTTP/1.1
Host: developer.mozilla.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0) Gecko/20100101 Firefox/50.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://developer.mozilla.org/testpage.html
Connection: keep-alive
Upgrade-Insecure-Requests: 1
If-Modified-Since: Mon, 18 Jul 2016 02:36:04 GMT
If-None-Match: "c561c68d0ba92bbeb8b0fff2a9199f722e3a621a"
Cache-Control: max-age=0
字段名 | 说明 | 示例 |
---|---|---|
Accept | 能够接受的回应内容类型(Content-Types) | Accept: text/plain |
Accept-Charset | 能够接受的字符集 | Accept-Charset: utf-8 |
Accept-Encoding | 能够接受的编码方式列表 | Accept-Encoding: gzip, deflate |
Accept-Language | 能够接受的回应内容的自然语言列表 | Accept-Language: en-US |
Authorization | 用于超文本传输协议的认证的认证信息 | Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== |
Cache-Control | 用来指定在这次的请求/响应链中的所有缓存机制 都必须 遵守的指令 | Cache-Control: no-cache |
Connection | 该浏览器想要优先使用的连接类型 | Connection: keep-alive Connection: Upgrade |
Cookie | 服务器通过 Set- Cookie (下文详述)发送的一个 超文本传输协议Cookie | Cookie: $Version=1; Skin=new; |
Content-Length | 以 八位字节数组 (8位的字节)表示的请求体的长度 | Content-Length: 348 |
Content-Type | 请求体的 多媒体类型 | Content-Type: application/x-www-form-urlencoded |
Date | 发送该消息的日期和时间 | Date: Tue, 15 Nov 1994 08:12:31 GMT |
Expect | 表明客户端要求服务器做出特定的行为 | Expect: 100-continue |
Host | 服务器的域名(用于虚拟主机 ),以及服务器所监听的传输控制协议端口号 | Host: en.wikipedia.org:80 Host: en.wikipedia.org |
If-Match | 仅当客户端提供的实体与服务器上对应的实体相匹配时,才进行对应的操作。主要作用时,用作像 PUT 这样的方法中,仅当从用户上次更新某个资源以来,该资源未被修改的情况下,才更新该资源 | If-Match: “737060cd8c284d8af7ad3082f209582d” |
If-Modified-Since | 允许在对应的内容未被修改的情况下返回304未修改 | If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT |
If-None-Match | 允许在对应的内容未被修改的情况下返回304未修改 | If-None-Match: “737060cd8c284d8af7ad3082f209582d” |
If-Range | 如果该实体未被修改过,则向我发送我所缺少的那一个或多个部分;否则,发送整个新的实体 | If-Range: “737060cd8c284d8af7ad3082f209582d” |
Range | 仅请求某个实体的一部分 | Range: bytes=500-999 |
User-Agent | 浏览器的浏览器身份标识字符串 | User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:12.0) Gecko/20100101 Firefox/21.0 |
Origin | 发起一个针对 跨来源资源共享 的请求 | Origin: http://www.example-social-network.com |
GET 和 POST 的区别
- 参数传递方式:GET通过Url传递参数,POST所有操作对用户来说都是不可见的。
- 传送数据量大小不同:GET传送的数据量较小,POST传送的数据量较大。
- 信息缓存:GET提交的信息能被缓存,POST提交的数据一般不能被缓存。
- 安全性:GET请求没有POST请求那么安全,因为参数都放在URL中。
- 请求方式:GET请求一般是去取获取数据,POST请求一般是去提交数据。
- 请求刷新与回退:GET请求刷新服务器或者回退没有影响,POST请求回退时会重新提交数据请求。
- 浏览器历史记录:GET请求可以被保存在浏览器历史记录当中,POST不会。
常见响应码
1xx (信息性状态码)
- 100 Continue:客户端应当继续发送请求。这个状态码表示服务器已经收到了部分请求,并且客户端应当继续发送请求的其余部分,或者如果请求已经完成,则忽略这个状态码。
- 101 Switching Protocols:服务器根据客户端的请求切换协议。例如,在Upgrade头字段中指定的另一种协议。
2xx (成功状态码)
- 200 OK:请求成功。请求所希望的响应头或数据体将随此响应返回。
- 204 No Content:服务器成功处理了请求,但没有返回任何内容。
- 205 Reset Content:服务器成功处理了请求,但没有返回任何内容,并且希望客户端重置文档视图(例如,清除表单内容以准备新输入)。
- 206 Partial Content:服务器已经成功处理了部分GET请求。类似于视频的分段下载或者断点续传。
3xx (重定向状态码)
- 301 Moved Permanently:请求的资源已被永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个URI之一。
- 302 Found(或1.1版本中的307 Temporary Redirect):临时重定向。由于某种原因,资源临时被分配了新的URL,但客户端应当继续使用原始URL进行后续的请求。
- 303 See Other:对应当前请求的响应可以在另一个URI上被找到,而且客户端应当采用GET方法访问那个资源。
- 304 Not Modified:如果客户端发送了一个带条件的GET请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个状态码。
- 307 Temporary Redirect:临时重定向。与302类似,但期望客户端在后续请求中保持相同的请求方法。
4xx (客户端错误状态码)
- 400 Bad Request:请求报文存在语法错误,服务器无法理解。
- 401 Unauthorized:类似于“未授权”,表示发送的请求需要有通过HTTP认证的认证信息。
- 403 Forbidden:服务器理解了请求客户端的请求,但是拒绝执行此请求。
- 404 Not Found:服务器上找不到请求的资源。
5xx (服务器错误状态码)
- 500 Internal Server Error:服务器遇到了一个未曾预料到的情况,导致其无法完成对请求的处理。
- 501 Not Implemented:服务器不支持当前请求所需要的某个功能。
- 503 Service Unavailable:由于临时的服务器维护或者过载,服务器当前无法处理请求。这是一个临时的状态,并且应当在一段时间后恢复。
HTTP响应状态码是用于表示服务器对客户端请求的响应状态的三位数字代码;
这些状态码被分为五类:
- **1xx:**信息性
- **2xx:**成功
- **3xx:**重定向
- **4xx:**客户端错误
- **5xx:**服务器错误
每一类状态码都有其特定的含义和用途;
帮助客户端和服务器端理解和处理请求和响应过程中的各种情况。
Cookie和Session
HTTP协议中的Cookie和Session都是用来跟踪浏览器状态的技术;
区别如下:
- **存储位置:**Cookie是存储在客户端的,而Session是存储在服务器端的。
- **安全性:**Cookie的安全性一般,因为Cookie是存储在客户端的,所以用户可以看到并修改它。Session的安全性相对较高,因为Session是存储在服务器端的,用户无法看到或修改它。
- **生命周期:**Cookie的生命周期是通过Expires或Max-Age来控制的,如果设置了过期时间,那么当时间到达后,Cookie就会被自动删除。而Session的生命周期是由服务器来控制的,当客户端关闭浏览器或者Session超时后,Session就会被删除。
- **存储大小:**Cookie的存储大小有限制,一般浏览器只允许存储4KB左右的数据。而Session的存储大小相对较大,可以存储更多的数据。
手写Scoket验证
# WEB应用程序:遵循HTTP协议(必须现有请求再有响应)
import socket
sock = socket.socket()
sock.bind(("127.0.0.1", 8090))
sock.listen(5)
while True:
connection, address = sock.accept() # 阻塞等待,等待客户端请求后建立连接
data = connection.recv(1024)
print("客户端发送的请求信息:")
print("----------")
print(data)
print("----------")
# connection.send(b"Hello World") # 可以接受请求,但是响应无效,浏览器无法处理
# 响应客户端的信息(请看“请求和响应协议流程图”)
# 第一个\r\n的前面是“请求首行”
# 第二个\r\n的前面是“请求头”(可以多个,但是一旦遇到两个\r\n就说明遇到请求体了)
# 两个\r\n的后面是“请求体”
# 这样才符合WEB应用遵循的HTTP协议(必须包含三部分数据)
# 测试1:纯文本展示在页面中
# connection.send(b"HTTP/1.1 200 OK\r\nServer-Name:Test\r\n\r\nHello World")
# 测试2:HTML展示在页面中
# connection.send(b"HTTP/1.1 200 OK\r\nServer-Name:Test\r\ncontent-type:text/html\r\n\r\n<h1>Hello World</h1>")
# 测试3:JSON展示在页面中
connection.send(b'HTTP/1.1 200 OK\r\nServer-Name:Test\r\ncontent-type:application/json\r\n\r\n{"name": "zhangsan", "age": "18", "city": "shanghai"}')
connection.close()