本篇文章是爲了後面的Django做準備的,這是學習web框架的底層知識,沒有直接用到socket,而是用Python自帶的庫wsgiref。
1、wsgiref模塊
它就相當於是一個服務器,會幫我們做解析,內部已經封裝好了socket等多項功能。
2、框架主要分爲五部分
1)導入模塊
from wsgiref.simple_server import make_server
2)自定義處理函數
def foo1(req):
f=open("index1.html","rb") # 讀取文件
data=f.read()
return data
3)路由分發函數
即分發其他函數的一個函數,所有的要實現的功能都可以放在這裏面傳輸到服務器,這樣每一個路徑都可以對應一個函數。
def router():
url_patterns=[
("/login",login),
("/register",register),
("/Viewin", foo1),
("/Zoro", foo2),
("/show_time",show_time),
]
return url_patterns
4)應用函數
框架本體,可以直接套用。一但有端口連接進入後,就會運行application函數,environ是wsgiref服務器處理傳入的請求信息,是一個大字典,取值用鍵值對來取。
def application(environ, start_response):
# 在application函數內,則需要作出響應操作
#通過environ來取路徑上輸入的值
print("path",environ["PATH_INFO"])
path= environ["PATH_INFO"]
# start_response設置響應頭:狀態碼爲200,狀態碼解析是OK,文本內容,文本格式...
start_response('200 OK', [('Content-Type', 'text/html')])
# return返回響應體
return [b"<h1>Hello, web!</h1>"]
5)創建鏈接並監聽HTTP請求
參數:IP地址,端口,應用函數
注意:這裏的IP地址會默認獲取本機的IP地址
# 創建鏈接
httpd = make_server('', 8080, application)
# 開始監聽HTTP請求:
httpd.serve_forever()
3、前端代碼body部分
1)show_time
<body>
<h1>時間:{{time}}</h1>
<!--自定義語法{{}}-->
</body>
2)login
<form action="http://192.168.43.247:8080/login" method="get">
<p>用戶:<input type="text" name="user"> </p>
<p>密碼:<input type="password" name="pwd"> </p>
<p><input type="submit">提交</p>
</form>
3)index1
<h1>Hello ViewIn!</h1>
4)index2
<h1>Hello Zoro!</h1>
4、參考效果
5、完整web框架
# 導入wsgiref模塊(不會直接使用socket),
# 它相當於是一個服務器,會幫我們做解析,內部已經封裝好了socket等多項功能
from wsgiref.simple_server import make_server
import time
# 自定義處理函數
def foo1(req):
f=open("index1.html","rb") # 讀取文件
data=f.read()
return data
def foo2(req):
f = open("index2.html", "rb") # 讀取文件
data = f.read()
return data
def login(req):
# print(req) #找到user和pwd所在的大的鍵爲QUERY_STRING
print(req["QUERY_STRING"])
return b"Welcome to my web!"
def register(req):
pass
def show_time(req):
times=time.ctime() # 獲取時間的字符串
f= open("show_time.html","rb")
data= f.read().decode("utf8")
# 自定義語法{{}},來找到我們需要的時間
# 用變量times(準確的時間)去替換頁面內的time
data= data.replace("{{time}}",str(times))
# 此處替換後的內容是字符串,因此需要轉碼一下
return data.encode("utf8")
# 路由分發的函數:即分發其他函數的一個函數,所有的要實現的功能都可以放在這裏面傳輸到服務器
# 這樣每一個路徑都可以對應一個函數
def router():
url_patterns=[
("/login",login),
("/register",register),
("/Viewin", foo1),
("/Zoro", foo2),
("/show_time",show_time),
]
return url_patterns
# 應用函數:一但有端口連接進入後,就會運行application函數
# environ是wsgiref服務器處理傳入的請求信息,是一個大字典,取值用鍵值對來取
def application(environ, start_response):
# 在application函數內,則需要作出響應操作
#通過environ來取路徑上輸入的值
print("path",environ["PATH_INFO"])
path= environ["PATH_INFO"]
# start_response設置響應頭:狀態碼爲200,狀態碼解析是OK,文本內容,文本格式...
start_response('200 OK', [('Content-Type', 'text/html')])
'''
if path=="/Viewin":
return[foo1()]
# return[b"<h1>Hello ViewIn!</h1>"] # 傳入網頁的應該是字節類型(二進制),並且最終應該包含在一個大字典裏
elif path=="/Zoro":
return[foo2()]
# return[b"<h1>Hello Zoro!</h1>"]
'''
# 接收路由分發函數
url_patterns=router()
func=None # 用來裝中間函數的
# 遍歷路由分發裏的函數
for item in url_patterns:
# 如果遍歷的對象和路徑輸入一致,則執行這個路徑對應的函數
if item[0]==path:
func=item[1]
break
# 因爲默認的None,所以需要判斷一下是否爲空
if func:
return[func(environ)] # 執行中間函數,並將路徑上獲取的信息作爲參數傳入
else:
return [b"<h1>404</h1>"]
# return返回響應體
return [b"<h1>Hello, web!</h1>"]
# 參數:IP地址,端口,應用函數
# 注意:這裏的IP地址會默認獲取本機的IP地址
httpd = make_server('', 8080, application)
print('Serving HTTP on port 8080...')
# 開始監聽HTTP請求:
httpd.serve_forever()