网络编程(part12)--HTTP传输
鄙人學習筆記
文章目錄
- HTTP協議 (超文本傳輸協議)
- 用途
- 特點
- 網頁請求過程
- HTTP請求(request)
- 請求行
- 請求頭
- 空行
- 請求體
- 舉個例子
- HTTP響應(response)
- 響應行
- 響應頭
- 空行
- 響應體
- 舉個例子
- 案例
HTTP協議 (超文本傳輸協議)
用途
網頁獲取,數據的傳輸
特點
①應用層協議,傳輸層使用TCP傳輸(HTTP作為應用層協議,自然也規定了自己的傳輸層協議,它采用TCP協議)
②簡單,靈活,很多語言都有HTTP專門接口
③協議不記錄傳輸內容
④http1.1 支持持久連接,豐富了請求類型
網頁請求過程
①客戶端(瀏覽器)通過TCP傳輸,發送http請求給服務端
②服務端接收到http請求后進行解析
③服務端處理請求內容,組織響應內容
④服務端將響應內容以http響應格式發送給瀏覽器
⑤瀏覽器接收到響應內容,解析展示
網頁請求圖示:
HTTP請求(request)
HTTP請求的格式為:
●請求行
●請求頭
●空行
●請求體
請求行
體現具體的請求類別和請求內容(想要干什么)
-
格式
-
請求類別:不同的請求類別,表示要做不同的事情(不同的需求)
| GET | 獲取網絡資源(比如,想得到一個網頁) |
| POST | 提交一定的信息,得到反饋(比如,想要注冊賬號) |
| HEAD | 只獲取網絡資源的響應頭 |
| PUT | 更新服務器資源(比如,在百度網盤中上傳文件) |
| DELETE | 刪除服務器資源(比如,在百度網盤中刪除文件) |
| CONNECT | - |
| TRACE | 測試 |
| OPTIONS | 獲取服務器性能信息 |
備注1:GET和HEAD都是獲取網絡資源。GET是直接從服務器將資源全部獲取進來;而HEAD請求,則是只獲取一份資源的介紹,這時,我們就可以通過這份介紹判斷資源是不是我們想要的
備注2:官方提示我們,想做什么請求,就用什么請求類型。但在實踐中,用GET和POST請求幾乎能解決所有的問題。
- 請求內容
比如: 【www.csdn.net/ 】
后的【/】就是我們的請求內容,它相當于我們網站的主頁。類似于我們的根目錄。
再比如: 【https://www.csdn.net/nav/python】
后的【/nav/python】同樣也是我們的請求內容。類似于在根目錄下進入了下一層級的目錄。
由上述例子可知,我們可以根據請求內容來具體定位。
請求頭
對請求的進一步解釋和描述(比如:請求發起的時間,請求發起的主機,請求發起的瀏覽器)
- 格式(鍵值對,鍵表達含義,值表達內容):
備注:請求頭會有很多鍵值對,但是一個鍵值對占一行。
空行
空行就是就是空一行。
請求體
請求參數或者提交內容
- 請求參數:比如,在百度中搜索的內容就是一種參數
- 提交內容:比如,我們要注冊百度賬號。填寫的用戶名、手機號、密碼等等…
舉個例子
(HTTP請求)
服務端代碼:
我們運行服務端代碼,并用Chrome瀏覽器向IP地址:127.0.0.1:8888發送HTTP請求:
服務端輸出:
由輸出結果可知:
GET / HTTP/1.1 為請求行
Host: 127.0.0.1:8888、Connection: keep-alive、User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.84 Safari/537.36等…為請求頭(都由鍵值對組成),它們分別表示:從IP地址為127.0.0.1:8888的主機發起的請求、保持長連接、使用Windows NT 6.3操作系統和Chrome瀏覽器等…
控制臺輸出結果最后的\r\n為空行
在以上結果中,我們沒有看到沒有請求體。這是因為,瀏覽器并沒有提交什么請求內容。
瀏覽器輸出:
沒有內容,為啥?因為我們的創建的服務端壓根沒給別人返回內容。
HTTP響應(response)
HTTP響應的格式為:
●響應行
●響應頭
●空行
●響應體
響應行
反饋基本的響應情況
- 格式
備注:響應碼和附加信息是成套的。
- 響應碼
| 1xx | 提示信息,表示請求被接收 |
| 2xx | 響應成功(比如:200,服務器已成功處理了請求) |
| 3xx | 響應需要進一步操作,重定向 |
| 4xx | 客戶端錯誤(比如:404,(未找到)服務器找不到請求的網頁) |
| 5xx | 服務器錯誤 |
響應頭
對響應內容的描述(比如:響應是什么時間發送的,響應的內容多大,響應是什么格式的)
- 格式(鍵值對,鍵表達含義,值表達內容):
空行
空行依然是空行。
響應體
響應的主體內容信息(請求端所需要的內容)
舉個例子
(我們上面的案例并沒能反饋給瀏覽器內容,所以瀏覽器啥都沒有。這里,我們發送一些內容)
我們發送一個OK:
我們運行服務端代碼,并用Chrome瀏覽器向IP地址:127.0.0.1:8888發送HTTP請求:
服務端輸出:
瀏覽器輸出:
WC….瀏覽器說我們服務端發送的響應無效???這時為什么??
我們再換成火狐瀏覽器康康。
服務端輸出:
瀏覽器輸出:
收到啦~
為啥火狐瀏覽器可以,而Chrome會拒絕呢?這是因為:我們應該要按照HTTP響應格式進行響應,但是我們發送的b”OK”是字節串,不是HTTP響應格式。然而,火狐瀏覽器比較人性,當火狐瀏覽器接收到內容不符合HTTP響應格式,它會自動把這些內容當成響應體,在網頁中呈現出來。但如果用谷歌Chrome瀏覽器,Chrome一看,接收到的內容壓根不符合HTTP響應格式,則Chrome不會進行內容的解析,也不會將發送的響應直接呈現出來,所以用Chrome不行。
如果我們想所有瀏覽器都能呈現我們發送的內容,該咋整?我們就要將發送的內容改為HTTP響應格式。
服務端代碼:
我們運行服務端代碼,并再用Chrome瀏覽器向IP地址:127.0.0.1:8888發送HTTP請求,得到輸出結果。
服務端結果:
Chrome瀏覽器結果:
成功啦!
雖然這只是一個簡單的小實驗,但是,我們訪問百度的過程和這個實驗的過程沒有太大區別。我們向瀏覽器反饋了hello world Huang’s web,就相當于百度服務器向瀏覽器反饋了一個文件(網頁就是一個文件)。
備注:百度后端存著很多網頁(文件)
案例
(自己構建一個html文件,并通過服務端反饋給瀏覽器)
在項目文件夾下,構建的HTML文件my_html.html :
服務端代碼:
#-*- coding: utf-8 -*- """ Created on Sat Feb 8 21:17:58 2020@author: goatbishop """from socket import *#處理瀏覽器的http請求 def handle(connfd):print("Request from", connfd.getpeername()) request = connfd.recv(4096) # 接收http請求# 防止客戶端斷開if not request:#若客戶端連接上服務端后,又異常退出#則request會接收到一個空值#若不對request進行判斷則后面的代碼會報錯!return#通過觀察請求格式,我們想將request按行進行分割#splitlines()為將按照行分割request_line = request.splitlines()[0].decode()#通過觀察請求行格式,我們選擇用空格分隔收到的信息,從而獲取請求內容#獲取請求內容info = request_line.split(' ')[1]if info == '/':f = open('my_html.html', encoding='utf-8')response = "HTTP/1.1 200 OK\r\n"response += "Content-Type: text/html\r\n"response += '\r\n'response += f.read()else:response = "HTTP/1.1 404 Not Found\r\n"response += "Content-Type: text/html\r\n"response += '\r\n'response += "<h1>Sorry....</h1>"# 向瀏覽器發送內容connfd.send(response.encode())#搭建TCP網絡 def main():sockfd = socket()sockfd.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)sockfd.bind(('0.0.0.0', 8888))sockfd.listen(3)print("Listen the port 8888...")while True:connfd, addr = sockfd.accept()print("已經接收.")handle(connfd) # 處理瀏覽器請求connfd.close()if __name__ == "__main__":main()我們運行服務端代碼,并用Chrome瀏覽器向IP地址:127.0.0.1:8888發送HTTP請求,得到輸出結果。
服務端輸出結果:
我們發現,我們同時接收到了很多請求。這是因為瀏覽器有一個機制:瀏覽器發送請求可能會得不到內容,所以它會自動的重新發送多次請求。比如說:當Chrome瀏覽器向某服務器發送1次請求,但沒有得到內容,則它會重新發送請求。若Chrome瀏覽器發送了很多次請求,依然得不到內容,瀏覽器才會確定:我們的確得不到內容了。
Chrome瀏覽器輸出結果:
若我們在Chrome瀏覽器中輸入127.0.0.1:8888/bunny則瀏覽器不會返回正確的頁面,如下圖所示:
這是因為請求的內容為:【/bunny】,而不是【/】,所以服務端向瀏覽器反饋了一個【Sorry….】
總結
以上是生活随笔為你收集整理的网络编程(part12)--HTTP传输的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网络编程(part11)--socket
- 下一篇: 宝可梦大集结岩殿居蟹技能好用吗 岩殿居蟹