目录
[【4.1】HTTP 0.9](#【4.1】HTTP 0.9)
[【4.2】HTTP 1.0](#【4.2】HTTP 1.0)
[【4.3】HTTP 1.1](#【4.3】HTTP 1.1)
[【4.4】HTTP 2.0](#【4.4】HTTP 2.0)
[【4.5】HTTP 3.0](#【4.5】HTTP 3.0)
一、Web应用程序
Web应用程序是一种可以通过Web访问的应用程序,程序的最大好处是用户很容易访问应用程序,用户只需要有浏览器即可,不需要再安装其他软件。应用程序有两种模式C/S、B/S。
C/S:客户端<----->服务端 例如MySQL C和S均装在同一台机器上
- C链接S: cmd窗口中 -----》mysql -h 127.0.0.1 -P 3306 -uroot -p密码
- 网络协议:一般情况,都是软件自定制协议---》基本都是基于TCP
B/S:浏览器<----->服务端 例如:Django运行后------》服务端
- 客户端链接 ----》浏览器
- 网络协议:所有全都是http协议-----》基于TCP
- 如果不是http协议,浏览器识别不了
注:
- B/S本质就是C/S
- B/S好处-------》软件更新了-------》只需要后端更新-------》前端是浏览器,不需要变---------》直接访问,看到的就是最新的
二、基于SOCKET写一个web应用
python
import socket
def server_run():
soc = socket.socket()
soc.bind(('127.0.0.1', 8008))
soc.listen(5)
while True:
conn, addr = soc.accept()
recv_data = conn.recv(1024)
print(recv_data)
# 1 直接在send里写,发送给客户端
# conn.send(b'HTTP/1.1 200 OK\r\n\r\n<h1>hello web</h1><img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2Fbba4f396-c3d4-4701-8ee3-bdab4cb3feba%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1703680132&t=35bd520feddfa57cc22dd58acb1016e4"></img>')
#2 打开一个html文件,发送给客户端
# with open('index.html','r',encoding='utf-8') as f:
# data=f.read()
# conn.send(('HTTP/1.1 200 OK\r\n\r\n%s'%data).encode('utf-8'))
# 3 动态网页,字符串替换
import time
now=time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
print(now)
with open('index.html','r',encoding='utf-8') as f:
data=f.read()
data=data.replace('@@@',now)
conn.send(('HTTP/1.1 200 OK\r\n\r\n%s'%data).encode('utf-8'))
conn.close()
if __name__ == '__main__':
server_run()
- index.html
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h2>@@@</h2>
<img src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2Fbba4f396-c3d4-4701-8ee3-bdab4cb3feba%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1703680132&t=35bd520feddfa57cc22dd58acb1016e4" alt="">
</body>
</html>
三、HTTP协议
1、http协议是什么?
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)
2、作用是什么?
是用于服务器与本地浏览器之间传输超文本的传送协议。
3、其特点是什么?
- 基于TCP/IP协议之上的应用层协议
- 它是可靠传输
- 基于请求-响应模式
- 必须客户端主动发起 ------》服务端才有响应
- 无状态保存
- HTTP是一种不保存状态,即无状态(stateless)协议
- 发送多次请求,对于服务端来讲,都是新的
- 无连接
- 无连接的含义是限制每次连接只处理一个请求
- 客户端不会一直跟服务端链接
4、HTTP版本及其区别
【4.1】HTTP 0.9
- 第一个版本的HTTP协议
- 只有GET一种请求,不支持请求头
- 无状态
- 每个事务独立进行,事务结束就断开连接
【4.2】HTTP 1.0
- 请求和响应支持头域
- 响应对象以一个响应状态行开始
- 响应对象不只限于超文本
- 开始支持客户端通过POST方法向Web服务器提交数据,支持GET,POST方法
- 短链接
- 每一个请求建立一个TCP连接,请求完成后立马断开连接
【4.3】HTTP 1.1
- 特点
- 1、简单:HTTP基本的报文格式:header+body,头部信息格式:key - value文本形式
- 2、灵活,易扩展
- 各类请求方法、URL、状态码,等每个组成都没有固定死,开发者可以自定义和扩充
- HTTP在应用层其下层可以灵活变化(https就是HTTP与TCP之间增加SSL/TSL安全传输协议)
- 3、应用广泛、支持跨平台
- 优缺点
- 1、无状态
- 好处:服务器不用额外资源记录,减轻服务器负担,提高CPU内存liyongxiaolv
- 坏处:每次都要确认验证信息;一般使用Cookie解决(Cookie 通过在请求和响应报文中写入 Cookie 信息来控制客户端的状态。)
- 2、明文传输
- 传输过程中信息可以抓包直接获取,信息暴露,安全性差
- 3、不安全
- 通信使用明文传输,信息泄露
- 不验证通信双方身份,有可能进入伪装网站
- 无法证明报文完整性导致不安全的问题
- 1、无状态
- 解决方式:
- 解压使用HTTPS协议,也就是通过引入SSL\TLS层
- 长连接
- 解决每次都要建立连接导致通信效率低的性能问题
- 好处
- 减少TCP连接的重复建立和断开所造成的的额外开销,减轻了服务端的负载
- 特点
- 只有任意一端没有明确提出断开连接,则保持TCP连接状态。
- 如果某个HTTP长连接超过一定时间没有任何数据交互,服务端就会主动断开这个连接
管道传输
- 管道传输:即可在同一个TCP连接里面,客户端可以发起多个请求,只要第一个请求发出去了,不必等其返回,就可以发出第二个请求出去,可以减少整体的响应时间
- 但是服务器必须按照接收请求的顺序发送对这些管道请求的响应
- HTTP1.1版本管道解决的请求的对头阻塞,没有解决响应的对头阻塞
【4.4】HTTP 2.0
- 特性:
- 二进制分帧
- 多路复用
- 在共享TCP链接的基础上同时发送请求和响应
- 头部压缩
- 服务器推送
- 服务器可以额外的向客户端推送资源,而无需客户端明确请求
二进制分帧
- HTTP 1.x 的解析是基于文本,HTTP 2之后将所有传输的信息分割为更小的消息和帧,并对它们采用二进制格式的编码,提高传输效率
多路复用
- 在共享TCP链接的基础上同时发送请求和响应,基于二进制分帧,在同一域名下所有访问都是从同一个tcp连接中走,http消息被分解为独立的帧,乱序发送,服务端根据标识符和首部将消息重新组装起来。
头部压缩
- 维护一个头部信息字典,差量进行更新头信息,减少头部信息传输占用的资源
【4.5】HTTP 3.0
- 传输层协议为UDP
- 采用QUIC机制(可靠机制)
- 三次握手建立连接,目的,确认连接ID
- 特点:
- 无对头阻塞
- 连接建立
- 连接迁移
5、http请求协议与响应协议
请求协议
- 请求首行:POST /?name=lqz&age=18 HTTP/1.1\r\n
- 请求方式:GET、POST
- 请求地址:/?name=lqz&age=18
- 请求协议版本号:HTTP/1.1\r\n
- 请求头:key:value形式 \r\n \r\n\r\n
- referer:上一次访问的地址
- user-agenet:客户端类型
- name:kevin
- cookie:只要是当前域【https://www.cnblogs.com/】中有的cookie,当次请求就会携带
- 请求体:get请求一般没有请求体,post请求有请求体
python
##### GET请求##### #####
'''
########### 请求首行####################
GET / HTTP/1.1\r\n
# get请求后面的参数
GET /?name=lqz&age=18 HTTP/1.1\r\n
##################### 请求头####################
Host: 127.0.0.1:8008\r\n
Connection: keep-alive\r\n
Cache-Control: max-age=0\r\n
Upgrade-Insecure-Requests: 1\r\n
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\nAccept-Encoding: gzip, deflate, br\r\n
Accept-Language: zh-CN,zh;q=0.9\r\n
Cookie: csrftoken=7xx6BxQDJ6KB0PM7qS8uTA892ACtooNbnnF4LDwlYk1Y7S7nTS81FBqwruizHsxF\r\n\r\n'
################ 请求体####################
(get请求,请求体为空)
'''
python
##### POST请求##### #####
'''
################请求首行################
POST /?name=lqz&age=18 HTTP/1.1\r\n
################请求头################
Host: 127.0.0.1:8008\r\n
Connection: keep-alive\r\n
Content-Length: 21\r\n
Cache-Control: max-age=0\r\n
Origin: http://127.0.0.1:8008\r\n
Upgrade-Insecure-Requests: 1\r\n
Content-Type: application/x-www-form-urlencoded\r\n
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\n
Referer: http://127.0.0.1:8008/?name=lqz&age=18\r\n
Accept-Encoding: gzip, deflate, br\r\nAccept-Language: zh-CN,zh;q=0.9\r\n
Cookie: csrftoken=7xx6BxQDJ6KB0PM7qS8uTA892ACtooNbnnF4LDwlYk1Y7S7nTS81FBqwruizHsxF\r\n\r\n
################请求体################
name=lqz&password=123'
'''
响应协议
- 响应首行:HTTP/1.1 200 OK\r\n
- 协议版本
- 响应状态码
- 响应描述符
- 响应头:key-value形式 cookie带在响应头中 -----》浏览器会把它存到浏览器的cookie中
- 响应体:一般给个html标签;浏览器中看到的页面,都是响应体的内容
python
# 响应首行
HTTP/1.1 200 OK
# 响应头
Date: Thu, 19 Sep 2019 08:08:27 GMT
Server: WSGIServer/0.2 CPython/3.7.3
Content-Type: application/json
Content-Length: 37
X-Frame-Options: SAMEORIGIN
Vary: Cookie
# 响应体
{"ret": 0, "retlist": [], "total": 0}
补充:
- post 既能带在地址栏中数据,又能带在请求体中数据
- get请求一般都带在地址栏中
请求一个网址:
https://www.cnblogs.com/liuqingzheng/articles
域名(https://www.cnblogs.com)+路径(liuqingzheng/articles)
携带数据到后端:有哪几种方式?
- 带在地址栏中 -----> 域名+路径+参数
- https://www.cnblogs.com/liuqingzheng/articles?name=xx\&age=111
- django从:requets.GET request.get_full_path
- 带在请求体中 ----》http的请求体 ----》多种编码格式
- json:后期会多使用它
- urlencoded:form表单,默认
- form-data:传文件
- django从:request.POST request.body
- 带在请求头中
- django中哪里取 request.META ---> 取出请求头
- 服务端响应给客户端数据
- 响应头中
- 用的最多:响应体
6、有哪些常用响应状态码

2**成功响应相关
2** 范围的状态码,表示服务器已成功接收到请求并进行处理。
代码 | 说明 |
---|---|
200 | (成功) 服务器已成功处理了请求。 通常,这表示服务器提供了请求的网页。 |
201 | (已创建) 请求成功并且服务器创建了新的资源。 |
202 | (已接受) 服务器已接受请求,但尚未处理。 |
203 | (非授权信息) 服务器已成功处理了请求,但返回的信息可能来自另一来源。 |
204 | (无内容) 服务器成功处理了请求,但没有返回任何内容。 |
205 | (重置内容) 服务器成功处理了请求,但没有返回任何内容。 |
206 | (部分内容) 服务器成功处理了部分 GET 请求 |
3**重定向相关
3** 范围的状态码,表示表示服务器要求客户端重定向,需要客户端进一步的操作以完成资源的请求。
状态码 | 状态英文名称 | 中文描述 |
---|---|---|
301 | Moved Permanently | 永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替。 |
302 | Found | 临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI。 |
304 | Not Modified | 未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源(响应消息中不包含响应体)。客户端通常会缓存访问过的资源。 |
4**客户端响应相关
4** 范围的状态码,表示客户端的请求有非法内容,从而导致这次请求失败。
状态码 | 状态英文名称 | 中文描述 |
---|---|---|
401 | Unauthorized | 当前请求需要用户验证。 |
403 | Forbidden | 服务器已经理解请求,但是拒绝执行它。 |
404 | Not Found | 请求失败。服务器无法根据客户端的请求找到资源(网页)。 |
408 | Request Timeout | 请求超时。服务器等待客户端发送的请求时间过长,超时。 |
400 | Bad Request | 1、语义有误,当前请求无法被服务器理解。除非进行修改,否则客户端不应该重复提交这个请求。2、请求参数有误。 |
5**服务端响应相关
5** 范围的状态码,表示服务器未能正常处理客户端的请求而出现意外错误。
状态码 | 状态英文名称 | 中文描述 |
---|---|---|
500 | Internal Server Error | 服务器遇到了不知道如何处理的情况。 |
501 | Not Implemented | 此请求方法不被服务器支持且无法被处理。只有GET和HEAD是要求服务器支持的,它们必定不会返回此错误代码。 |
503 | Service Unavailable | 服务器没有准备好处理请求。由于超载或系统维护,服务器暂时的无法处理客户端的请求。 |
7、常用的http请求头
Header | 解释 | 示例 |
---|---|---|
Accept | 指定客户端能够接收的内容类型 | Accept: text/plain, text/html |
Accept-Charset | 浏览器可以接受的字符编码集。 | Accept-Charset: iso-8859-5 |
Accept-Encoding | 指定浏览器可以支持的web服务器返回内容压缩编码类型。 | Accept-Encoding: compress, gzip |
Accept-Language | 浏览器可接受的语言 | Accept-Language: en,zh |
Accept-Ranges | 可以请求网页实体的一个或者多个子范围字段 | Accept-Ranges: bytes |
Authorization | HTTP授权的授权证书 | Authorization: 授权证书 |
Cache-Control | 指定请求和响应遵循的缓存机制 | Cache-Control: no-cache |
Connection | 表示是否需要持久连接。(HTTP 1.1默认进行持久连接) | Connection: close |
Cookie | HTTP请求发送时,会把保存在该请求域名下的所有cookie值一起发送给web服务器。 | Cookie: $Version=1; Skin=new; |
Content-Length | 请求的内容长度 | Content-Length: 348 |
Content-Type | 请求的与实体对应的MIME信息 | Content-Type: application/x-www-form-urlencoded |
Date | 请求发送的日期和时间 | Date: Tue, 15 Nov 2010 08:12:31 GMT |
Expect | 请求的特定的服务器行为 | Expect: 100-continue |
From | 发出请求的用户的Email | From: [email protected] |
Host | 指定请求的服务器的域名和端口号 | Host: www.jsons.cn |
If-Match | 只有请求内容与实体相匹配才有效 | If-Match: "特定值" |
If-Modified-Since | 如果请求的部分在指定时间之后被修改则请求成功,未被修改则返回304代码 | If-Modified-Since: Sat, 29 Oct 2010 19:43:31 GMT |
If-None-Match | 如果内容未改变返回304代码,参数为服务器先前发送的Etag,与服务器回应的Etag比较判断是否改变 | If-None-Match: "特定值" |
If-Range | 如果实体未改变,服务器发送客户端丢失的部分,否则发送整个实体。参数也为Etag | If-Range: "特定值" |
If-Unmodified-Since | 只在实体在指定时间之后未被修改才请求成功 | If-Unmodified-Since: Sat, 29 Oct 2010 19:43:31 GMT |
Max-Forwards | 限制信息通过代理和网关传送的时间 | Max-Forwards: 10 |
Pragma | 用来包含实现特定的指令 | Pragma: no-cache |
Proxy-Authorization | 连接到代理的授权证书 | Proxy-Authorization: 链接到代理的授权证书 |
Range | 只请求实体的一部分,指定范围 | Range: bytes=500-999 |
Referer | 先前网页的地址,当前请求网页紧随其后,即来路 | Referer: http://www.jsons.cn |
TE | 客户端愿意接受的传输编码,并通知服务器接受接受尾加头信息 | TE: trailers,deflate;q=0.5 |
Upgrade | 向服务器指定某种传输协议以便服务器进行转换(如果支持) | Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11 |
User-Agent | User-Agent的内容包含发出请求的用户信息 | User-Agent: Mozilla/5.0 (Linux; X11) |
Via | 通知中间网关或代理服务器地址,通信协议 | Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1) |
Warning | 关于消息实体的警告信息 | Warn: 199 Miscellaneous warning |
8、常用的http响应头
Header | 解释 | 示例 |
---|---|---|
Accept-Ranges | 表明服务器是否支持指定范围请求及哪种类型的分段请求 | Accept-Ranges: bytes |
Age | 从原始服务器到代理缓存形成的估算时间(以秒计,非负) | Age: 12 |
Allow | 对某网络资源的有效的请求行为,不允许则返回405 | Allow: GET, HEAD |
Cache-Control | 告诉所有的缓存机制是否可以缓存及哪种类型 | Cache-Control: no-cache |
Content-Encoding | web服务器支持的返回内容压缩编码类型。 | Content-Encoding: gzip |
Content-Language | 响应体的语言 | Content-Language: en,zh |
Content-Length | 响应体的长度 | Content-Length: 348 |
Content-Location | 请求资源可替代的备用的另一地址 | Content-Location: /index.htm |
Content-MD5 | 返回资源的MD5校验值 | Content-MD5: MD5校验值 |
Content-Range | 在整个返回体中本部分的字节位置 | Content-Range: bytes 21010-47021/47022 |
Content-Type | 返回内容的MIME类型 | Content-Type: text/html; charset=utf-8 |
Date | 原始服务器消息发出的时间 | Date: Tue, 15 Nov 2010 08:12:31 GMT |
ETag | 请求变量的实体标签的当前值 | ETag: "请求变量实体标签当前值" |
Expires | 响应过期的日期和时间 | Expires: Thu, 01 Dec 2010 16:00:00 GMT |
Last-Modified | 请求资源的最后修改时间 | Last-Modified: Tue, 15 Nov 2010 12:45:26 GMT |
Location | 用来重定向接收方到非请求URL的位置来完成请求或标识新的资源 | Location: http://www.jsons.cn |
Pragma | 包括实现特定的指令,它可应用到响应链上的任何接收方 | Pragma: no-cache |
Proxy-Authenticate | 它指出认证方案和可应用到代理的该URL上的参数 | Proxy-Authenticate: Basic |
refresh | 应用于重定向或一个新的资源被创造,在5秒之后重定向(由网景提出,被大部分浏览器支持) | Refresh: 5; url= http://www.jsons.cn |
Retry-After | 如果实体暂时不可取,通知客户端在指定时间之后再次尝试 | Retry-After: 120 |
Server | web服务器软件名称 | Server: Apache/1.3.27 (Unix) (Red-Hat/Linux) |
Set-Cookie | 设置Http Cookie | Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1 |
Trailer | 指出头域在分块传输编码的尾部存在 | Trailer: Max-Forwards |
Transfer-Encoding | 文件传输编码 | Transfer-Encoding:chunked |
Vary | 告诉下游代理是使用缓存响应还是从原始服务器请求 | Vary: * |
Via | 告知代理客户端响应是通过哪里发送的 | Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1) |
Warning | 警告实体可能存在的问题 | Warning: 199 Miscellaneous warning |
WWW-Authenticate | 表明客户端请求实体应该使用的授权方案 | WWW-Authenticate: Basic |
9、URL简介
统一资源定位符是对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它
格式:
协议://IP:端口(80)/路径?name=lqz&age=18
http协议,如果不写端口号 ----》默认是80
?之前的是请求路径,?之后的是请求数据部分
补充
get请求能携带请求体吗?
HTTP 协议没有为 GET 请求的 body 赋予语义,也就是即不要求也不禁止 GET 请求带 body。
大多数 HTTP 实现从技术上都支持 HTTP GET 请求带 body,少数实现会禁止(google-chrome 浏览器、node-fetch),少数实现会不建议(Fiddler)。
软件工程中有一条原则:不要依赖未定义的行为。HTTP 协议未定义 GET 请求的 body 语义,如果想用 GET 请求发送 body,得先为其定义语义,并确保上下游都能很好的支持。作为服务接口的提供方,不应该假设所有的调用方都能发出 GET 请求 body;作为调用方,不应该假设服务方能完美解析 GET 请求 body,但如果服务方提供了支持 GET 请求 body 的接口,可以放心使用,不用纠结。
软件工程中还有另一条原则,不记得原文了,翻译成中国的老话就是:严于律己,宽已待人。我们在写库、写框架、写工具时应该支持 GET 请求带 body;在封装接口时,尽量不要强制调用方用 GET body 提交数据,除非遇到用 GET body 才符合逻辑的特殊情况;在使用别人提供的库、框架、工具,或者调用协作方提供的接口时不应该强求对方支持 GET 请求 body。