基於socke手擼web框架css
# 請求首行 b'GET / HTTP/1.1\r\n #GET /index HTTP/1.1\r\n (index)爲瀏覽器請求地址) # 請求頭 Host: 127.0.0.1:8080\r\n Connection: keep-alive\r\n Cache-Control: max-age=0\r\n Upgrade-Insecure-Requests: 1\r\n # User-Agent用來標識是否是瀏覽器 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.132 Safari/537.36\r\n Sec-Fetch-Mode: navigate\r\n Sec-Fetch-User: ?1\r\n Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3\r\n Sec-Fetch-Site: none\r\n Accept-Encoding: gzip, deflate, br\r\n Accept-Language: zh-CN,zh;q=0.9\r\n \r\n 請求體
import socket server = socket.socket() server.bind(('127.0.0.1',8080)) server.listen(5) while True: conn, addr = server.accept() data = conn.recv(1024) conn.send(b'HTTP/1.1 200 OK\r\n\r\n') print(data) data = data.decode('utf-8') current_path = data.split('\r\n')[0].split(' ')[1] # print(current_path) if current_path == '/index': # conn.send(b'index') with open(r'D:\python脫產10期視頻\day51\01 純手擼html文件.html','rb') as f: conn.send(f.read()) elif current_path == '/login': conn.send(b'login') else: conn.send(b'hello world!') conn.close()
字符山與二進制字符串轉換技巧html
data = b'hello world' data = str(data,encoding='utf-8') print(data) data = bytes(data,encoding='utf-8') print(data)
基於wsgiref(主要是方便先後端交互的軟件)和jinja2(模板渲染)手擼web框架前端
from wsgiref.simple_server import make_server from 代碼.urls import urls from 代碼.views import * def run(env,response): """ env是請求相關的數據 response是響應相關的數據 """ # print(env) response('200 OK',[]) current_path = env.get('PATH_INFO') # print(current_path) # if current_path == '/index': # return [b'index'] # elif current_path == '/login': # return [b'login'] # 定義一個存儲函數名的標誌位 func = None for url in urls: # 判斷當前url在不在元組內 if url[0] == current_path: # 只要匹配上了 就把url後綴對應的函數名賦值給func func = url[1] # 一旦匹配上 應該馬上退出for循環 節省資源 break # 對變量func作判斷 if func: res = func(env) else: res = errors(env) return [res.encode('utf-8')] if __name__ == '__main__': server = make_server('127.0.0.1',8080,run) # 實時監測127.0.0.1:8080地址 一旦有客戶端來鏈接 會自動加括號調用run方法 server.serve_forever() # 啓動服務端
代碼/url.pypython
from 代碼.views import * urls = [ ('/index',index), ('/login',login), ('/reg',reg), ('/get_time',get_time), ('/get_user',get_user), ('/get_db',get_db), ]
代碼/views.pymysql
def index(env): return 'index' def login(env): return 'login' def errors(env): return '404 error' def reg(env): return 'reg' from datetime import datetime def get_time(env): # 藉助於時間模塊 如今後端獲取到時間數據 current_time = datetime.now().strftime('%Y-%m-%d %X') with open(r'templates/02 get_time.html','r',encoding='utf-8') as f: data = f.read() # data其實就是一串字符串 僅此而已!!! data = data.replace('$$time$$',current_time) return data from jinja2 import Template def get_user(env): user_dict = {'username':'jason','password':'123','hobby':['read','game','running']} with open(r'templates/03 get_user.html','r',encoding='utf-8') as f: data = f.read() temp = Template(data) # data爲html讀出來的全部字符串 res = temp.render(data = user_dict) # 將user_dict傳遞給前端頁面 前端頁面經過變量名data(html頁面中的{{data}})就可以獲取到該字典 return res import pymysql def get_db(env): conn = pymysql.connect( host = '127.0.0.1', port = 3306, user = 'root', password = '123', database = 'day51', charset = 'utf8', autocommit = True ) cursor = conn.cursor(pymysql.cursors.DictCursor) sql = "select * from userinfo" affect_rows = cursor.execute(sql) data = cursor.fetchall() # print(data) with open(r'templates/04 get_db.html','r',encoding='utf-8') as f: data1 = f.read() temp = Template(data1) res = temp.render(user_list= data) return res
templatesjquery
#01 純手擼html文件 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> </head> <body> <h1>要放假了 好嗨皮</h1> </body> </html> #02 get_time.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> </head> <body> $$time$$ </body> </html> # 03 get_user.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> </head> <body> <p>{{data}}</p> <p>{{data['username']}}</p> <p>{{data.password}}</p> <p>{{data.get('hobby')}}</p> </body> </html> # 04 get_db.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <link href="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"> <script src="https://cdn.bootcss.com/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <h2 class="text-center">用戶數據展現</h2> <table class="table table-hover table-bordered table-striped"> <thead> <tr> <th>id</th> <th>username</th> <th>password</th> </tr> </thead> <tbody> {%for user_dict in user_list%} <tr> <td>{{user_dict.id}}</td> <td>{{user_dict.name}}</td> <td>{{user_dict.password}}</td> </tr> {%endfor%} </tbody> </table> </div> </div> </div> </body>
模板渲染web
1.模板語法:前端可使用後端語言的語法,來操做後端傳過來的數據sql
靜態網頁
數據是寫死的,萬年不變
動態網頁
數據不是寫死的 是動態獲取到的
好比:
1.後端實時獲取當前時間"傳遞"給前端頁面展現
2.後端從數據庫獲取數據"傳遞"給前端頁面展現數據庫
頁面渲染:後端把數據傳給前端的過程,並把前端改爲本身想要的樣式。bootstrap
總結:
.純手擼web框架 1.手動書寫socket代碼 2.手動處理http數據 2.基於wsgiref模塊幫助咱們處理scoket以及http數據 wsgiref模塊 1.請求來的時候 解析http數據 幫你打包成一個字典傳輸給你 便於你操做各項數據 2.響應走的時候 自動幫你把數據再打包成符合http協議格式的樣子 再返回給前端 3.封裝路由與視圖函數對應關係 以及視圖函數文件 網站用到的全部的html文件所有放在了templates文件夾下 1.urls.py 路由與視圖函數對應關係 2.views.py 視圖函數(視圖函數不僅僅指函數 也能夠是類) 3.templates 模板文件夾 4.基於jinja2實現模板的渲染 模板的渲染 後端生成好數據 經過某種方式傳遞給前端頁面使用(前端頁面能夠基於模板語法更加快捷簡便使用後端傳過來的數據)