一、最簡單的WEB頁面訪問過程
互聯網應用都要經過通過OSI層封裝解封裝來達到遠程訪問效果。python中有寫好的socket模塊幫助開發人員實現這個功能,因此開發人員只要把注意力放在客戶端和服務端。對于WEB來說,客戶端就是瀏覽器,服務端則是提供頁面的程序所在的機器。客戶端已有成熟的各種瀏覽器,那么做出符合各種需求的頁面就比較關鍵。
(1)首先模擬服務器程序
一個簡單套import socket #導入socket模塊
sock = socket.socket()#實例化socket對象
sock.bind(('127.0.0.1',9000)) #綁定ip地址和端口號
sock.listen(5) #設置監聽的客戶端數量
while True:
conn, ddr = sock.accept()#conn是客戶端和服務端建立的鏈接,ddr是客戶端地址加端口號
print(conn)#<socket.socket fd=440, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0,
laddr=('127.0.0.1', 9000), raddr=('127.0.0.1', 57951)>
print(ddr)#('127.0.0.1', 57951)
data = conn.recv(1024) #接受客戶端訪問的數據
conn.send(b'HTTP/1.1 200 OK\r\n\r\nhello web') # 向客戶端發送數據,因為使用的瀏覽器,所以要加個HTTP標準格式,不然瀏覽器無法解析
使用瀏覽器訪問:

以上就是最基礎的WEB訪問過程,服務器返回的是一個二進制字符串數據,瀏覽器解析后變為正常的字符串顯示在頁面,而實際中則是要復雜得多。
(2)使用html顯示頁面
如果想構建復雜頁面,光靠一行行send二進制信息給瀏覽器解析是很不方便的。一方面不便于編寫,另一方面也不適合維護。所以通過寫html文件,然后利用open函數讀取htlm,再發送給瀏覽器解析則方便許多。
代碼修改:
import socket #導入socket模塊
sock = socket.socket()#實例化socket對象
sock.bind(('127.0.0.1',9000)) #綁定ip地址和端口號
sock.listen(5) #設置監聽的客戶端數量
while True:
conn, ddr = sock.accept()#conn是客戶端和服務端建立的鏈接,ddr是客戶端地址加端口號
data = conn.recv(1024) # 接受客戶端訪問的數據
with open('index.html','r') as f:
data_html = f.read()
conn.send(("HTTP/1.1 200 OK\r\n\r\n%s"%data_html).encode('utf-8')) # 向客戶端發送html文件的二進制信息
這樣只要單獨編寫html文件,然后通過讀取文件方式再發送給瀏覽器,就可以方便的實現更復雜的頁面效果。
(3)HTTP的請求和響應
我們先看看上述最簡單的WEB訪問程序如何工作的。
通過瀏覽器開發者選項下的Network可以看到:

瀏覽器通過向服務器發送GET請求來獲得響應,實際是得到了服務器返回的html代碼然后解析成對應的頁面。下面簡單介紹HTTP請求過程。
HTTP請求報文由三部分組成:請求行,請求頭和請求正文
b'GET / HTTP/1.1\r\nHost: 127.0.0.1:9000\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; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36\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'
請求行:指的是“GET / HTTP/1.1”,這種指明請求類型(有get或post)、URL路徑、HTTP協議和版本號的代碼行。
請求頭:指的是由\r\n分割的代碼內容。里面包含了Host、Connection等信息。
請求正文:指的是由\r\n\r\n分割的代碼內容。
HTTP響應報文也有三部分構成:響應行,響應頭和實體內容
"HTTP/1.1 200 OK\r\nContent-Type:text/html\r\n\r\n%s"%data_html
響應行:指的是\r\n前面的HTTP協議及版本號和狀態碼。其中狀態碼有1XX、2XX、3XX、4XX、5XX等,通常1XX表示在正在處理接受的請求,2XX表示請求處理完畢、3XX表示重定向,
指的是服務器返回給瀏覽器需要重新訪問的頁面地址,相當于兩次HTTP請求過程。4XX通常表示客戶端請求錯誤指的是URL不正確等,5XX表示的是服務器處理請求出錯,為服務端程序錯誤。
響應頭:指的是\r\n和\r\n\r\n中間的內容,在瀏覽器中可以看到:
實體內容:指的是r\n\r\n之后的代碼,也是瀏覽器要解析的html代碼,通過它瀏覽器才能解析、渲染來向用戶提供頁面。

浙公網安備 33010602011771號