zoukankan      html  css  js  c++  java
  • 自定义web框架

    web框架的根本是socket的代码,那么我们可以基于socket服务端的十几行代码写一个我们自己的web框架。

    我们先不处理浏览器发送的请求,先让浏览器能显示我们web框架返回的信息,那我们就要按照HTTP协议的格式来发送响应。

     1 import socket    
     2     
     3 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)    
     4 sock.bind(('127.0.0.1', 8000))    
     5 sock.listen()    
     6     
     7 while True:    
     8     conn, addr = sock.accept()    
     9     data = conn.recv(8096)    
    10     # 给回复的消息加上响应状态行    
    11     conn.send(b"HTTP/1.1 200 OK
    
    ")    
    12     conn.send(b"OK")    
    13     conn.close()    
    web框架核心代码

    下面就是继续完善自定义的web框架。

    1. 根据不同的路径返回不同的内容

    现在的一个问题就是如何让我们的web服务根据用户请求的URL不同,然后返回不同的内容?

    这个问题,我们可以从请求相关数据里面拿到请求URL的路径,然后拿路径做一个判断。

     1 import socket  
     2   
     3 sk = socket.socket()  
     4 sk.bind(("127.0.0.1", 8080))  # 绑定IP和端口  
     5 sk.listen()  # 监听  
     6   
     7 while True:  
     8     # 等待连接  
     9     conn, add = sk.accept()  
    10     data = conn.recv(8096)  # 接收客户端发来的消息  
    11     # 从data中取到路径  
    12     data = str(data, encoding="utf8")  # 把收到的字节类型的数据转换成字符串  
    13     # 按
    分割  
    14     data1 = data.split("
    ")[0]  
    15     url = data1.split()[1]  # url是我们从浏览器发过来的消息中分离出的访问路径  
    16     conn.send(b'HTTP/1.1 200 OK
    
    ')  # 因为要遵循HTTP协议,所以回复的消息也要加状态行  
    17     # 根据不同的路径返回不同内容  
    18     if url == "/index/":  
    19         response = b"index"  
    20     elif url == "/home/":  
    21         response = b"home"  
    22     else:  
    23         response = b"404 not found!"  
    24   
    25     conn.send(response)  
    26     conn.close()  
    根据URL中不同的路径返回不同的内容

    2. 根据不同的路径返回不同的内容——函数版

    上面的代码解决了不同的URL路径,返回不同内容的需求。

    返回的内容只是简单的几个字符,那么可以将返回的内容封装成一个函数。

     1   
     2 import socket  
     3   
     4 sk = socket.socket()  
     5 sk.bind(("127.0.0.1", 8080))  # 绑定IP和端口  
     6 sk.listen()  # 监听  
     7   
     8   
     9 # 将返回不同的内容部分封装成函数  
    10 def func(url):  
    11     s = "这是{}页面!".format(url)  
    12     return bytes(s, encoding="utf8")  
    13   
    14   
    15 while True:  
    16     # 等待连接  
    17     conn, add = sk.accept()  
    18     data = conn.recv(8096)  # 接收客户端发来的消息  
    19     # 从data中取到路径  
    20     data = str(data, encoding="utf8")  # 把收到的字节类型的数据转换成字符串  
    21     # 按
    分割  
    22     data1 = data.split("
    ")[0]  
    23     url = data1.split()[1]  # url是我们从浏览器发过来的消息中分离出的访问路径  
    24     conn.send(b'HTTP/1.1 200 OK
    
    ')  # 因为要遵循HTTP协议,所以回复的消息也要加状态行  
    25     # 根据不同的路径返回不同内容,response是具体的响应体  
    26     if url == "/index/":  
    27         response = func(url)  
    28     elif url == "/home/":  
    29         response = func(url)  
    30     else:  
    31         response = b"404 not found!"  
    32   
    33     conn.send(response)  
    34     conn.close()  
    根据URL中不同的路径返回不同的内容--函数版

    3. 根据不同的路径返回不同内容——函数进阶版

    上面的代码只是简单的写了一个函数,那么继续延伸下去,就可以写多个函数,不同的路径对应执行不同的函数拿到结果。

     1 import socket  
     2   
     3 sk = socket.socket()  
     4 sk.bind(("127.0.0.1", 8080))  # 绑定IP和端口  
     5 sk.listen()  # 监听  
     6   
     7   
     8 # 将返回不同的内容部分封装成不同的函数  
     9 def index(url):  
    10     s = "这是{}页面XX!".format(url)  
    11     return bytes(s, encoding="utf8")  
    12   
    13   
    14 def home(url):  
    15     s = "这是{}页面。。!".format(url)  
    16     return bytes(s, encoding="utf8")  
    17   
    18   
    19 # 定义一个url和实际要执行的函数的对应关系  
    20 list1 = [  
    21     ("/index/", index),  
    22     ("/home/", home),  
    23 ]  
    24   
    25 while True:  
    26     # 等待连接  
    27     conn, add = sk.accept()  
    28     data = conn.recv(8096)  # 接收客户端发来的消息  
    29     # 从data中取到路径  
    30     data = str(data, encoding="utf8")  # 把收到的字节类型的数据转换成字符串  
    31     # 按
    分割  
    32     data1 = data.split("
    ")[0]  
    33     url = data1.split()[1]  # url是我们从浏览器发过来的消息中分离出的访问路径  
    34     conn.send(b'HTTP/1.1 200 OK
    
    ')  # 因为要遵循HTTP协议,所以回复的消息也要加状态行  
    35     # 根据不同的路径返回不同内容  
    36     func = None  # 定义一个保存将要执行的函数名的变量  
    37     for item in list1:  
    38         if item[0] == url:  
    39             func = item[1]  
    40             break  
    41     if func:  
    42         response = func(url)  
    43     else:  
    44         response = b"404 not found!"  
    45   
    46     # 返回具体的响应消息  
    47     conn.send(response)  
    48     conn.close()  
    根据URL中不同的路径返回不同的内容--函数进阶版

    4. 根据不同的路径返回不同的内容——函数进阶版(返回具体的HTML文件)

    如果想给浏览器返回完整的HTML内容,那么又应该怎么做呢?

    不管是什么内容,最后都是转换成字节数据发送出去。我们可以打开HTML文件,读取出它内部的二进制文件,然后再发送给浏览器。

     1 import socket  
     2   
     3 sk = socket.socket()  
     4 sk.bind(("127.0.0.1", 8080))  # 绑定IP和端口  
     5 sk.listen()  # 监听  
     6   
     7   
     8 # 将返回不同的内容部分封装成不同的函数  
     9 def index(url):  
    10     # 读取index.html页面的内容  
    11     with open("index.html", "r", encoding="utf8") as f:  
    12         s = f.read()  
    13     # 返回字节数据  
    14     return bytes(s, encoding="utf8")  
    15   
    16   
    17 def home(url):  
    18     with open("home.html", "r", encoding="utf8") as f:  
    19         s = f.read()  
    20     return bytes(s, encoding="utf8")  
    21   
    22   
    23 # 定义一个url和实际要执行的函数的对应关系  
    24 list1 = [  
    25     ("/index/", index),  
    26     ("/home/", home),  
    27 ]  
    28   
    29 while True:  
    30     # 等待连接  
    31     conn, add = sk.accept()  
    32     data = conn.recv(8096)  # 接收客户端发来的消息  
    33     # 从data中取到路径  
    34     data = str(data, encoding="utf8")  # 把收到的字节类型的数据转换成字符串  
    35     # 按
    分割  
    36     data1 = data.split("
    ")[0]  
    37     url = data1.split()[1]  # url是我们从浏览器发过来的消息中分离出的访问路径  
    38     conn.send(b'HTTP/1.1 200 OK
    
    ')  # 因为要遵循HTTP协议,所以回复的消息也要加状态行  
    39     # 根据不同的路径返回不同内容  
    40     func = None  # 定义一个保存将要执行的函数名的变量  
    41     for item in list1:  
    42         if item[0] == url:  
    43             func = item[1]  
    44             break  
    45     if func:  
    46         response = func(url)  
    47     else:  
    48         response = b"404 not found!"  
    49   
    50     # 返回具体的响应消息  
    51     conn.send(response)  
    52     conn.close() 
    服务器

    index.html中的代码

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <meta http-equiv="x-ua-compatible" content="IE=edge">
     6     <meta name="viewport" content="width=device-width, initial-scale=1">
     7     <title>index</title>
     8 </head>
     9 <body>
    10 <div>这是index页面</div>
    11 </body>
    12 </html>
    index.html

    home.html中的代码

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <meta http-equiv="x-ua-compatible" content="IE=edge">
     6     <meta name="viewport" content="width=device-width, initial-scale=1">
     7     <title>index</title>
     8 </head>
     9 <body>
    10 <div>这是home页面</div>
    11 </body>
    12 </html>
    home.html

    5. 根据URL中不同的路径返回不同的内容——函数进阶版(返回独立的HTML页面)

     1 import time   
     2 import socket  
     3   
     4 sk = socket.socket()  
     5 sk.bind(("127.0.0.1", 8080))  # 绑定IP和端口  
     6 sk.listen()  # 监听  
     7   
     8   
     9 # 将返回不同的内容部分封装成不同的函数  
    10 def index(url):  
    11     # 读取index.html页面的内容  
    12     with open("index.html", "r", encoding="utf8") as f:  
    13         s = f.read()  
    14     # 返回字节数据  
    15     return bytes(s, encoding="utf8")  
    16   
    17   
    18 def home(url):  
    19     with open("home.html", "r", encoding="utf8") as f:  
    20         s = f.read()  
    21     return bytes(s, encoding="utf8")  
    22   
    23   
    24 def timer(url):  
    25     with open("time.html", "r", encoding="utf8") as f:  
    26         s = f.read()  
    27         s = s.replace('@@time@@', time.strftime("%Y-%m-%d %H:%M:%S"))  
    28     return bytes(s, encoding="utf8")  
    29   
    30   
    31 # 定义一个url和实际要执行的函数的对应关系  
    32 list1 = [  
    33     ("/index/", index),  
    34     ("/home/", home),  
    35     ("/time/", timer),  
    36 ]  
    37   
    38 while True:  
    39     # 等待连接  
    40     conn, add = sk.accept()  
    41     data = conn.recv(8096)  # 接收客户端发来的消息  
    42     # 从data中取到路径  
    43     data = str(data, encoding="utf8")  # 把收到的字节类型的数据转换成字符串  
    44     # 按
    分割  
    45     data1 = data.split("
    ")[0]  
    46     url = data1.split()[1]  # url是我们从浏览器发过来的消息中分离出的访问路径  
    47     conn.send(b'HTTP/1.1 200 OK
    
    ')  # 因为要遵循HTTP协议,所以回复的消息也要加状态行  
    48     # 根据不同的路径返回不同内容  
    49     func = None  # 定义一个保存将要执行的函数名的变量  
    50     for item in list1:  
    51         if item[0] == url:  
    52             func = item[1]  
    53             break  
    54     if func:  
    55         response = func(url)  
    56     else:  
    57         response = b"404 not found!"  
    58   
    59     # 返回具体的响应消息  
    60     conn.send(response)  
    61     conn.close()  
    服务器

    index.html代码

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <meta http-equiv="x-ua-compatible" content="IE=edge">
     6     <meta name="viewport" content="width=device-width, initial-scale=1">
     7     <title>index</title>
     8 </head>
     9 <body>
    10 <div>这是index页面</div>
    11 </body>
    12 </html>
    index.html

    home.html代码

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <meta http-equiv="x-ua-compatible" content="IE=edge">
     6     <meta name="viewport" content="width=device-width, initial-scale=1">
     7     <title>index</title>
     8 </head>
     9 <body>
    10 <div>这是home页面</div>
    11 </body>
    12 </html>
    home.html

    time.html代码

     1 <!doctype html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <meta name="viewport"
     6           content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
     7     <meta http-equiv="X-UA-Compatible" content="ie=edge">
     8     <title>Document</title>
     9 </head>
    10 <body>
    11 <h1>当前时间是:@@time@@</h1>
    12 </body>
    13 </html>
    time.html代码

     

     

  • 相关阅读:
    让Python支持中文注释
    【转】python入门指引
    【转】布同:如何循序渐进学习Python语言
    在nagios中监控windows主机系统地址的状态
    大神
    music
    20·15-01-21
    2015-01-20
    2015-01-19
    2015-01-18
  • 原文地址:https://www.cnblogs.com/yang-wei/p/9965995.html
Copyright © 2011-2022 走看看