Django(基础)

day60

http协议:https://www.cnblogs.com/liwenzhou/p/8620663.html

HTTP状态码

所有HTTP响应的第一行都是状态行,依次是当前HTTP版本号,3位数字组成的状态代码,以及描述状态的短语,彼此由空格分隔。

状态代码的第一个数字代表当前响应的类型:

  • 1xx消息——请求已被服务器接收,继续处理
  • 2xx成功——请求已成功被服务器接收、理解、并接受
  • 3xx重定向——需要后续操作才能完成这一请求
  • 4xx请求错误——请求含有词法错误或者无法被执行
  • 5xx服务器错误——服务器在处理某个正确请求时发生错误

虽然 RFC 2616 中已经推荐了描述状态的短语,例如"200 OK"(状态码 状态码描述),"404 Not Found",但是WEB开发者仍然能够自行决定采用何种短语,用以显示本地化的状态描述或者自定义信息。

HTTP请求格式

'GET / HTTP/1.1    请求行( 请求方法      协议版本)
Host: 127.0.0.1:8001    请求头部
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: keep-alive
Upgrade-Insecure-Requests: 1'

无请求数据

HTTP请求格式。

网页请求,后台回应。

===================================================================

HTTP响应格式

"""
不完善的web服务端示例
"""

import socket

# 生成socket实例对象
sk = socket.socket()
# 绑定IP和端口
sk.bind(("127.0.0.1", 8001))
# 监听
sk.listen()

# 写一个死循环,一直等待客户端来连我
while 1:
    # 获取与客户端的连接
    conn, _ = sk.accept()
    # 接收客户端发来消息
    data = conn.recv(8096)
    print(data)
    # HTTP响应格式  协议版本 状态码 状态码描述 回车符换行符
    conn.send(b'http/1.1 200 ok

')
    # 给客户端回复消息
    conn.send(b'<h1>hello s10!</h1>')
    # 关闭
    conn.close()
    sk.close()

# HTTP响应格式 协议版本 状态码 状态码描述 回车符换行符

conn.send(b'http/1.1 200 ok ')

按HTTP响应格式发送数据。

效果:

========================================================================================

响应头,请求头

 1 """
 2 不完善的web服务端示例
 3 """
 4 
 5 import socket
 6 
 7 # 生成socket实例对象
 8 sk = socket.socket()
 9 # 绑定IP和端口
10 sk.bind(("127.0.0.1", 8001))
11 # 监听
12 sk.listen()
13 
14 # 写一个死循环,一直等待客户端来连我
15 while 1:
16     # 获取与客户端的连接
17     conn, _ = sk.accept()
18     # 接收客户端发来消息
19     data = conn.recv(8096)
20     print(data)
21     # 给客户端回复消息
22     conn.send(b'http/1.1 200 OK
content-type:text/html; charset=utf-8

')
23     # 想让浏览器在页面上显示出来的内容都是响应正文
24     conn.send(b'<h1>hello s10!</h1>')
25     # 关闭
26     conn.close()
27     sk.close()

其中content-type:text/html; charset=utf-8在响应格式中属于响应头。

22行为响应格式。

关于HTTP协议:
            1. 浏览器往服务端发的叫 请求(request)
                请求的消息格式:
                    请求方法 路径 HTTP/1.1
                    k1:v1
                    k2:v2
                    
                    请求数据
                
            2. 服务端往浏览器发的叫 响应(response)
                响应的消息格式:
                    HTTP/1.1 状态码 状态描述符
                    k1:v1
                    k2:v2
                    
                    响应正文   <-- html的内容 

根据不同的路径返回不同的内容web服务端示例

 1 """
 2 完善的web服务端示例
 3 根据不同的路径返回不同的内容
 4 """
 5 
 6 import socket
 7 
 8 # 生成socket实例对象
 9 sk = socket.socket()
10 # 绑定IP和端口
11 sk.bind(("127.0.0.1", 8000))
12 # 监听
13 sk.listen()
14 
15 # 写一个死循环,一直等待客户端来连我
16 while 1:
17     # 获取与客户端的连接
18     conn, _ = sk.accept()
19     # 接收客户端发来消息
20     data = conn.recv(8096)
21     # 把收到的数据转成字符串类型
22     data_str = str(data, encoding="utf-8")  # bytes("str", enconding="utf-8")
23     # print(data_str)
24     # 用
去切割上面的字符串
25     l1 = data_str.split("
")
26     # print(l1[0])
27     # 按照空格切割上面的字符串
28     l2 = l1[0].split() #GET /xiaohei/ HTTP/1.1
  将第一行根据空格分开
29     url = l2[1] #取url  取第一行第二个数据
30     # 给客户端回复消息
31     conn.send(b'http/1.1 200 OK
content-type:text/html; charset=utf-8

')
32     # 想让浏览器在页面上显示出来的内容都是响应正文
33 
34     # 根据不同的url返回不同的内容
35     if url == "/yimi/":
36         response = b'<h1>hello yimi!</h1>'
37     elif url == "/xiaohei/":
38         response = b'<h1>hello xiaohei!</h1>'
39     else:
40         response = b'<h1>404! not found!</h1>'
41     conn.send(response)
42     # 关闭
43     conn.close()
44     sk.close()

根据不同路径返回不同内容。

动态的网页

不同时候访问,内容不同。

 1 """
 2 完善的web服务端示例
 3 函数版根据不同的路径返回不同的内容
 4 进阶函数版 不写if判断了,用url名字去找对应的函数名
 5 返回html页面
 6 返回动态的html页面
 7 """
 8 
 9 import socket
10 
11 # 生成socket实例对象
12 sk = socket.socket()
13 # 绑定IP和端口
14 sk.bind(("127.0.0.1", 8001))
15 # 监听
16 sk.listen()
17 
18 # 定义一个处理/yimi/的函数
19 def yimi(url):
20     with open("yimi.html", "r", encoding="utf-8") as f:#字符串类型读取
21        ret = f.read()
22     import time
23     # 得到替换后的字符串 html中内容被时间戳替换
24     ret2 = ret.replace("@@xx@@", str(time.time()))
25     return bytes(ret2, encoding="utf-8")
26 
27 
28 # 定义一个处理/xiaohei/的函数
29 def xiaohei(url):
30     with open("xiaohei.html", "rb") as f:#二进制读取
31        ret = f.read()
32     return ret
33 
34 
35 # 定义一个专门用来处理404的函数
36 def f404(url):
37     ret = "你访问的这个{} 找不到".format(url)
38     return bytes(ret, encoding="utf-8")
39 
40 
41 url_func = [
42     ("/yimi/", yimi),
43     ("/xiaohei/", xiaohei),
44 ]
45 
46 
47 # 写一个死循环,一直等待客户端来连我
48 while 1:
49     # 获取与客户端的连接
50     conn, _ = sk.accept()
51     # 接收客户端发来消息
52     data = conn.recv(8096)
53     # 把收到的数据转成字符串类型
54     data_str = str(data, encoding="utf-8")  # bytes("str", enconding="utf-8")
55     # print(data_str)
56     # 用
去切割上面的字符串
57     l1 = data_str.split("
")
58     # print(l1[0])
59     # 按照空格切割上面的字符串
60     l2 = l1[0].split()
61     url = l2[1]
62     # 给客户端回复消息
63     conn.send(b'http/1.1 200 OK
content-type:text/html; charset=utf-8

')
64     # 想让浏览器在页面上显示出来的内容都是响应正文
65 
66     # 根据不同的url返回不同的内容
67     # 去url_func里面找对应关系
68     for i in url_func:
69         if i[0] == url:
70             func = i[1]
71             break
72     # 找不到对应关系就默认执行f404函数
73     else:
74         func = f404
75     # 拿到函数的执行结果
76     response = func(url)
77     # 将函数返回的结果发送给浏览器
78     conn.send(response)
79     # 关闭连接
80     conn.close()

html文件

xiaohei.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>小黑</title>
</head>
<body>

<h1>day60 Web框架本质都讲了些啥啊</h1>

<p>小黑啊</p>
<p>啊,真的是黑啊!</p>
</body>
</html>

yimi.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>yimi</title>
</head>
<body>

<h1>day60 web框架的本质</h1>
<p>海燕</p>
<p>在苍茫的大海上,狂风卷积着乌云,在乌云和大海之间,海燕像黑色的闪电,在高傲的飞翔</p>

<a href="http://www.luffycity.com">程序员的梦想,点我直达</a>
<audio src="song.ogg" controls="controls"></audio>

<!--其中为被替换内容-->
<p>@@xx@@</p>
</body>
</html>

@@XX@@被替换。

动态的网页:
        本质上都是字符串的替换
    字符串替换发生在什么地方:
        在服务端替换完再返回给浏览器!!!

 总结一下:
        1. web框架的本质:
            socket服务端  与 浏览器的通信
        2. socket服务端功能划分:
            a. 负责与浏览器收发消息(socket通信)  --> wsgiref/uWsgi/gunicorn...
            
            b. 根据用户访问不同的路径执行不同的函数
            
            c. 从HTML读取出内容,并且完成字符串的替换  --> jinja2(模板语言)
            
        3. Python中 Web框架的分类:
            
            1. 按上面三个功能划分:
                1. 框架自带a,b,c                 --> Tornado
                2. 框架自带b和c,使用第三方的a    --> Django
                3. 框架自带b,使用第三方的a和c    --> Flask
            2. 按另一个维度来划分:
                1. Django   --> 大而全(你做一个网站能用到的它都有)
                2. 其他     --> Flask 轻量级

原文地址:https://www.cnblogs.com/112358nizhipeng/p/10278301.html