1、Web應用html
2、Web框架python
3、wsgiref模塊web
Web應用程序是一種能夠經過Web訪問的應用程序,特色是用戶很容易訪問,只須要有瀏覽器便可,不須要安裝其餘軟件。編程
應用程序有兩種模式,即C/S、B/S兩種,C/S是客戶端/服務器端程序,這類程序通常獨立運行;而B/S就是瀏覽器端/服務器端應用程序,這類應用程序通常藉助谷歌,火狐等瀏覽器來運行。Web應用程序通常是B/S模式。在網絡編程的意義下,瀏覽器是一個socket客戶端,服務器是一個socket服務端。flask
import socket # 導入模塊 def handle_request(client): request_data = client.recv(1024) # 接收數據 print('request data:',request_data) client.send('HTTP/1.1 200 OK\r\n\r\n'.encode('utf8')) # 發送請求 client.send("<h1 style='color:blue'>Hello world</h1>".encode('utf8')) def main(): sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 實例化 sock.bind(('localhost',8800)) # 指定鏈接的服務器及端口 sock.listen(5) # 監聽 while True: print('waiting....') connection,address = sock.accept() # 收到數據 handle_request(connection) #處理鏈接 connection.close() # 關閉鏈接 if __name__ == '__main__': main()
注意: 瀏覽器
報文格式: 請求/響應首行 請求/響應頭 請求頭 請求頭 ... 請求/響應體(如user=cc&pwd=123)# 注意:只有POST請求才會有請求體,請求頭與請求體之間使用「\r\n\r\n」進行區分,其他請求首行、請求頭之間均用「\r\n」分隔 b'GET / HTTP/1.1\r\nHost: 127.0.0.1:8080\r\nConnection: keep-alive\r\nCache-Control: max-age=0\r\nUpgrade-Insecure-Requests: 1\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.134 Safari/537.36 Vivaldi/2.5.1525.40\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: zh-CN,zh;q=0.9\r\n\r\n' b'POST / HTTP/1.1\r\nHost: 127.0.0.1:8080\r\nConnection: keep-alive\r\nContent-Length: 15\r\nCache-Control: max-age=0\r\nOrigin: http://127.0.0.1:8080\r\nUpgrade-Insecure-Requests: 1\r\nContent-Type: application/x-www-form-urlencoded\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.134 Safari/537.36 Vivaldi/2.5.1525.40\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3\r\nReferer: http://127.0.0.1:8080/\r\nAccept-Encoding: gzip, deflate, br\r\nAccept-Language: zh-CN,zh;q=0.9\r\n\r\nuser=cc&pwd=123'
Web框架(Web framework)是一種開發框架,用來支持動態網站、網絡應用和網絡服務的開發。服務器
大多數的web框架提供了一套開發和部署網站的方式,也爲web行爲提供了一套通用的方法,而且實現了許多功能,開發人員使用框架提供的方法能夠更快完成本身的業務邏輯,快速開發web應用,避免反覆造輪子,節省了許多時間和精力,大大提升了開發的效率。網絡
最簡單的Web應用就是先把HTML用文件保存好,用一個現成的HTTP服務器軟件,接收用戶請求,從文件中讀取HTML,返回。若是要動態生成HTML,就須要把上述步驟本身來實現。app
接受HTTP請求、解析HTTP請求、發送HTTP響應都是苦力活,若是咱們本身來寫這些底層代碼,還沒開始寫動態HTML呢,就得花很長時間去讀HTTP規範。框架
正確的作法是底層代碼由專門的服務器軟件實現,咱們用Python專一於生成HTML文檔。由於咱們不但願接觸到TCP鏈接、HTTP原始請求和響應格式,因此,須要一個統一的接口協議來實現這樣的服務器軟件,讓咱們專心用Python編寫Web業務。
這個接口就是WSGI:Web Server Gateway Interface。
wsgi協議簡單理解,就是wsgi server調用wsgi application接口的約定,即當有個請求到達wsgi server時,wsgi server經過調用wsgi application提供的接口來處理這個請求。
wsgiref模塊就是python基於wsgi協議開發的服務模塊。wsgiref模塊是由server和handler組成,server用於監聽端口,接收請求;handler用於處理請求。
#!/usr/bin/env python3 #!-*- coding:utf-8-*- # write by cc from wsgiref.simple_server import make_server def application(environ,start_response): # environ : 按照http協議解析數據,解析後的數據格式爲字典 # start_response : 按照http協議的格式組裝數據 print(environ,type(environ)) # <class 'dict'> # return [b"<h1>Hello Web</h1>"] # 返回的格式必須是列表,內容必須是二進制數據 path = environ.get("PATH_INFO") # 獲取當前路徑 start_response('200 Ok',[('Content_Type','text/html')]) # if path == '/index': with open('index.html','r') as f: data = f.read() elif path == '/login': with open('login.html','r') as f: data = f.read() return [data.encode('utf-8')] ''' environ = {'ALLUSERSPROFILE': 'C:\\ProgramData', 'APPDATA': 'C:\\Users\\CC9102\\AppData\\Roaming', 'COMMONPROGRAMFILES': 'C:\\Program Files\\Common Files', 'COMMONPROGRAMFILES(X86)': 'C:\\Program Files (x86)\\Common Files', 'COMMONPROGRAMW6432': 'C:\\Program Files\\Common Files', 'COMPUTERNAME': 'DESKTOP-3UMV17V', 'COMSPEC': 'C:\\Windows\\system32\\cmd.exe', 'DRIVERDATA': 'C:\\Windows\\System32\\Drivers\\DriverData', 'FPS_BROWSER_APP_PROFILE_STRING': 'Internet Explorer', 'FPS_BROWSER_USER_PROFILE_STRING': 'Default', 'HOMEDRIVE': 'C:', 'HOMEPATH': '\\Users\\CC9102', 'LOCALAPPDATA': 'C:\\Users\\CC9102\\AppData\\Local', 'LOGONSERVER': '\\\\DESKTOP-3UMV17V', 'NUMBER_OF_PROCESSORS': '4', 'ONEDRIVE': 'C:\\Users\\CC9102\\OneDrive', 'ONEDRIVECONSUMER': 'C:\\Users\\CC9102\\OneDrive', 'OS': 'Windows_NT', 'PATH': 'D:\\python37\\;D:\\python37\\Scripts\\;D:\\python27\\;D:\\python27\\Scripts;C:\\Windows\\system32;C:\\Windows;C:\\Windows\\System32\\Wbem;C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\;C:\\Windows\\System32\\OpenSSH\\;D:\\UltraEdit;D:\\Calibre\\;C:\\Users\\CC9102\\AppData\\Local\\Microsoft\\WindowsApps;D:\\Bandizip\\', 'PATHEXT': '.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.PY;.PYW', 'PROCESSOR_ARCHITECTURE': 'AMD64', 'PROCESSOR_IDENTIFIER': 'Intel64 Family 6 Model 61 Stepping 4, GenuineIntel', 'PROCESSOR_LEVEL': '6', 'PROCESSOR_REVISION': '3d04', 'PROGRAMDATA': 'C:\\ProgramData', 'PROGRAMFILES': 'C:\\Program Files', 'PROGRAMFILES(X86)': 'C:\\Program Files (x86)', 'PROGRAMW6432': 'C:\\Program Files', 'PSMODULEPATH': 'C:\\Program Files\\WindowsPowerShell\\Modules;C:\\Windows\\system32\\WindowsPowerShell\\v1.0\\Modules', 'PUBLIC': 'C:\\Users\\Public', 'PYCHARM_HOSTED': '1', 'PYTHONIOENCODING': 'UTF-8', 'PYTHONPATH': 'E:\\PyCharmFiles', 'PYTHONUNBUFFERED': '1', 'SESSIONNAME': 'Console', 'SYSTEMDRIVE': 'C:', 'SYSTEMROOT': 'C:\\Windows', 'TEMP': 'C:\\Users\\CC9102\\AppData\\Local\\Temp', 'TMP': 'C:\\Users\\CC9102\\AppData\\Local\\Temp', 'USERDOMAIN': 'DESKTOP-3UMV17V', 'USERDOMAIN_ROAMINGPROFILE': 'DESKTOP-3UMV17V', 'USERNAME': 'CC9102', 'USERPROFILE': 'C:\\Users\\CC9102', 'WINDIR': 'C:\\Windows', 'SERVER_NAME': 'DESKTOP-3UMV17V.DHCP HOST', 'GATEWAY_INTERFACE': 'CGI/1.1', 'SERVER_PORT': '8080', 'REMOTE_HOST': '', 'CONTENT_LENGTH': '', 'SCRIPT_NAME': '', 'SERVER_PROTOCOL': 'HTTP/1.1', 'SERVER_SOFTWARE': 'WSGIServer/0.2', 'REQUEST_METHOD': 'GET', 'PATH_INFO': '/', 'QUERY_STRING': '', 'REMOTE_ADDR': '127.0.0.1', 'CONTENT_TYPE': 'text/plain', 'HTTP_HOST': '127.0.0.1:8080', 'HTTP_CONNECTION': 'keep-alive', 'HTTP_CACHE_CONTROL': 'max-age=0', 'HTTP_UPGRADE_INSECURE_REQUESTS': '1', 'HTTP_USER_AGENT': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.134 Safari/537.36 Vivaldi/2.5.1525.40', 'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3', 'HTTP_ACCEPT_ENCODING': 'gzip, deflate, br', 'HTTP_ACCEPT_LANGUAGE': 'zh-CN,zh;q=0.9', 'wsgi.input': <_io.BufferedReader name=468>, 'wsgi.errors': <_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'>, 'wsgi.version': (1, 0), 'wsgi.run_once': False, 'wsgi.url_scheme': 'http', 'wsgi.multithread': True, 'wsgi.multiprocess': False, 'wsgi.file_wrapper': <class 'wsgiref.util.FileWrapper'>} <class 'dict'> 'PATH_INFO': '/', 'QUERY_STRING': '', 'REMOTE_ADDR': '127.0.0.1', 'CONTENT_TYPE': 'text/plain', 'HTTP_HOST': '127.0.0.1:8080', 'HTTP_CONNECTION': 'keep-alive', ''' # 封裝socket(實例化一個socket對象,並傳入參數) httped = make_server("",8080,application) # 等待用戶鏈接,至關於 conn,addr = sock.accept(),用戶鏈接後自動調用application方法 httped.serve_forever()
這個實例程序能夠看做是一個Web框架,它的實現過程就是這樣幾步:
第一步,寫一個Web應用(application),即wsgiref application,除了函數,也能夠是類(flask),參數爲 environ和start_response;
第二步,經過封裝socket,建立一個httped服務器,並監聽8080端口(可隨機指定,不與其餘程序端口衝突便可),等待用戶鏈接;
第三步,當有客戶端請求時獲得匹配,即用戶輸入對應網址時,在瀏覽器顯示對應的頁面。
注意兩點:
第一點:environ爲一個字典,保存系統變量以及請求相關屬性,例如請求路徑,請求參數,請求方法等等;start_response爲函數,設置response的狀態碼和header,而後application函數的返回值爲response的body。
第二點:response狀態碼設置爲200時,表示請求成功,在headers添加返回數據類型爲text/html,返回的數據必須爲二進制字符串。