共计 2774 个字符,预计需要花费 7 分钟才能阅读完成。
引入
在学习 Django 框架之前我们得先了解 Web 框架的本质是什么, 以及 HTTP 协议的原理
一. 软件开发架构
- C/S 指的是客户端软件(client)--- 服务端软件(server)
- B/S 指的是浏览器(Browser)------ 服务端软件(server)
ps : B/S 的本质就是 C/S
二.Web 框架的本质
所有的 Web 应用其实就是一个 socket 服务端, 而用户使用的浏览器就是一个 socket 客户端程序, 明白了 Web 框架的本质, 我们就可以实现自己的 Web 框架了
1. 自定义简单 Web 框架
import socket
server = socket.socket() # 默认就是基于网络的 TCP 协议
server.bind(("127.0.0.1",8080))
server.listen(5)
while 1:
conn,addr = server.accept()
data = conn.recv(1024)
print(data) # 将请求打印出来
conn.send(b"ok")
conn.close()
可以说 Web 服务的本质都是基于这简单的套接字程序扩展出来的
三.HTTP 协议
1.HTTP 怎么来的
用户使用浏览器访问一台服务器, 输入网址, 向服务端发送数据, 那么这个数据发的是一些什么? 怎么发送? 如果每个网站都有自己的要规则, 那整个互联网都乱套了, 用户访问不同的网站就很繁琐
所以, 就必须有一个统一的规则, 让大家发送数据或者接收数据的时候有一个依据; 而这个规则就是 HTTP 协议
2. 什么是 HTTP 协议
- 超文本传输协议, 规定了浏览器与服务端之间数据交互的格式
- 如果服务端不遵循该协议, 那么浏览器就不能正常访问
- 如果还想让用户访问, 那就自己开发客户端, 让用户下载你的 app
3.HTTP 的四大特征
- 基于 TCP/IP 作用于应用层之上的协议
- 基于请求响应 (向服务端发送请求, 服务端响应客户端请求)
- 无状态, 不保存用户状态信息
- 例 : 见你千百遍我都待你入初见
- 方案 : 因为 HTTP 协议的无状态, 后面又出了保存用户状态信息的技术 : cookie,session,token...
- 无 (短) 连接, 请求一次则响应一次, 之后就没有任何关系
- 方案 : 后面出现了 websocket 可以实现长链接, 可以让双方建立连接后默认不断开(QQ. 微信聊天)
4. 查看请求与相应的数据格式
HTTP 协议既然规定了客户端和服务器之间的通信格式,那 HTTP 协议是怎么规定消息格式的呢? 我们先运行下上面写的 socket 将请求数据打印出来看看
b'GET / HTTP/1.1\r\n ## 请求首行
Host: 127.0.0.1:8080\r\n ## 请求头 (下面都是, 一大堆的 K:V 键值对)
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 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.25 Safari/537.36 Core/1.70.3823.400 QQBrowser/10.7.4307.400\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\n
Accept-Encoding: gzip, deflate, br\r\n
Accept-Language: zh-CN,zh;q=0.9\r\n
Cookie: csrftoken=WCzjKvmjOSdJbYKs0uIfPtiFfLl04FENb6p9CjypP7ZObcUpydaQPLZN0qPOVqwj\r\n
\r\n' ## 换行
b'' ## 请求体
我们在来访问一下博客园, 查看浏览器收到的相应数据 : 在网页中鼠标右击检查 ---->Network----> 点击当前网页的网址 ---->Headers-----> 查看 Response Headers
通过 socket 服务端收到的请求以及图片中浏览器收到的响应可以发现收发消息都是按照一定的格式来的
5.HTTP GET 方法的请求格式
- 格式说明
// 请求首行 : 请求方法, 协议版本...
// 请求头 : 一大堆的 k:v 键值对
// 空行 \r\n : 用来标识作用
// 请求体 : 🔰并不是所有的请求方法都有, 只要用来携带敏感性数据(get 没有,post 有)
- 请求方式说明
1."get" 请求 : 朝服务端索要数据 (例 : 输入网址获取对应的内容)
2."post" 请求 : 朝服务端提交数据 (例 : 登入, 输入用户名密码, 提交到服务端进行校验)
- get 与 post 的区别
1. 都可以携带额外的参数 :
// GET 提交的数据会放在 URL 之后,以 "?" 分割 URL 和传输数据,参数之间以 "&" 相连
// POST 方法是把提交的数据放在 HTTP 包的请求体 (Body) 中.
2. 提交的数据大小限制 :
// 浏览器对 URL 长度有限制, 所以 GET 提交的数据大小有限制
// POST 方法没有数据大小限制
3. 数据的安全性 :
// GET 方式提交数据, 会带来安全问题, 比如一个登录页面, 通过 GET 方式提交数据时, 用户名和密码将出现在 URL 上
// 如果页面可以被缓存或者其他人可以访问这台机器, 就可以从历史记录获得该用户的账号和密码
6.HTTP 响应格式
- 格式说明
// 响应首行 : 响应状态码, 协议版本....
// 响应头 : 一大堆 k:v 键值对
// 空行 \r\n : 用来标识作用
// 响应体 : 响应正文, 展示给用户的数据
- 响应状态码说明
// 用简单的数字来表示一串中文意思(状态或者描述性信息)
1XX : 1 开头的, 服务端已经接受到你的数据正在处理,你可以继续提交
2XX : 200 OK>>> : 请求成功
3XX : 重定向(当你在访问一个需要登陆之后才能看的页面你会发现会自动跳转到登陆页面)
4XX : 403 当前请求不符合条件(没有权限), 404 请求资源不存在
5XX : 服务器内部错误, 无法完成请求
ps : 除了上面提到的响应码之外, 公司内部还会自定义自己的状态码, 一般 1000 以后
三.URL 统一资源定位符
形式 : scheme:[//[user:password@]host[:port]][/]path[?query-string][#anchor]
提示 : 方框内的是可选部分
-
scheme:协议(例如:http,https,ftp)
-
user : password@用户的登录名以及密码
-
host:服务器的 IP 地址或者域名
-
port:服务器的端口(如果是走协议默认端口,http 80 or https 443)
-
path:访问资源的路径
-
query-string:参数,它通常使用键值对来制定发送给 http 服务器的数据
-
anchor:锚(跳转到网页的指定锚点位置)