請先自學網絡部分:tcp\ip協議、OSI七層模型以及數據包的封裝與解封裝的過程html
HTTP協議(HyperText Transfer Protocol,超文本傳輸協議)是用於從萬維網(WWW:World Wide Web )服務器傳輸超文本到本地瀏覽器的傳送協議。。它可使瀏覽器更加高效,使網絡傳輸減小。它不只保證計算機正確快速地傳輸超文本文檔,還肯定傳輸文檔中的哪一部分,以及哪部份內容首先顯示(如文本先於圖形)等。http協議做用在應用層web
在瞭解HTTP如何工做以前,咱們先了解計算機之間的通訊。HTTP基於tcp/ip。瀏覽器
互聯網的關鍵技術就是TCP/IP協議。兩臺計算機之間的通訊是經過TCP/IP協議在因特網上進行的。實際上這個是兩個協議:緩存
TCP : Transmission Control Protocol 傳輸控制協議和IP: Internet Protocol 網際協議。安全
IP:計算機之間的通訊bash
IP協議是計算機用來相互識別的通訊的一種機制,每臺計算機都有一個IP.用來在internet上標識這臺計算機。 IP 負責在因特網上發送和接收數據包。經過 IP,消息(或者其餘數據)被分割爲小的獨立的包,並經過因特網在計算機之間傳送。IP 負責將每一個包路由至它的目的地。服務器
IP協議僅僅是容許計算機相互發消息,但它並不檢查消息是否以發送的次序到達並且沒有損壞(只檢查關鍵的頭數據)。爲了提供消息檢驗功能,直接在IP協議上設計了傳輸控制協議TCP.網絡
TCP : 應用程序之間的通訊session
TCP確保數據包以正確的次序到達,而且嘗試確認數據包的內容沒有改變。TCP在IP地址之上引端口(port),它容許計算機經過網絡提供各類服務。一些端口號爲不一樣的服務保留,並且這些端口號是衆所周知。架構
服務或者守護進程:在提供服務的機器上,有程序監聽特定端口上的通訊流。例如大多數電子郵件通訊流出如今端口25上,用於wwww的HTTP通訊流出如今80端口上。
當應用程序但願經過 TCP 與另外一個應用程序通訊時,它會發送一個通訊請求。這個請求必須被送到一個確切的地址。在雙方「握手」以後,TCP 將在兩個應用程序之間創建一個全雙工 (full-duplex) 的通訊,佔用兩個計算機之間整個的通訊線路。TCP 用於從應用程序到網絡的數據傳輸控制。TCP 負責在數據傳送以前將它們分割爲 IP 包,而後在它們到達的時候將它們重組。
TCP/IP 就是TCP 和 IP 兩個協議在一塊兒協同工做,有上下層次的關係。
TCP 負責應用軟件(好比你的瀏覽器)和網絡軟件之間的通訊。IP 負責計算機之間的通訊。TCP 負責將數據分割並裝入 IP 包,IP 負責將包發送至接受者,傳輸過程要經IP路由器負責根據通訊量、網絡中的錯誤或者其餘參數來進行正確地尋址,而後在它們到達的時候從新組合它們。
HTTP協議工做於客戶端-服務端架構上的協議。就是瀏覽器和服務器之間進行「溝通」的一種規範。瀏覽器做爲HTTP客戶端經過URL向HTTP服務端即WEB服務器發送全部請求。
HTTP三點注意事項:特色
其餘特色:
基於tcp/ip
基於請求/響應模式
客戶機與服務器創建鏈接後,發送一個請求給服務器,請求格式爲:統一資源標識符、協議版本號。服務器收到請求的信息(包括請求行,請求頭,請求體)。服務器接收到請求後,給予相應的響應信息,格式爲一個狀態行(包括響應行,響應頭,響應體)。 |
如用客戶端瀏覽器請求這個頁面:http://localhost.com:8080/index.htm
從中分解出協議名、主機名、端口、對象路徑等部分,對於咱們的這個地址,解析獲得的結果以下:
協議名:http
主機名:localhost.com
端口:8080
對象路徑:/index.html
在這一步,須要域名系統DNS解析域名localhost.com,得主機的IP地址。
把以上部分結合本機本身的信息,封裝成一個HTTP請求數據包
在HTTP工做開始以前,客戶機(Web瀏覽器)首先要經過網絡與服務器創建鏈接,該鏈接是經過TCP來完成的,該協議與IP協議共同構建Internet,即著名的TCP/IP協議族,所以Internet又被稱做是TCP/IP網絡。HTTP是比TCP更高層次的應用層協議,根據規則,只有低層協議創建以後才能,才能進行更高層協議的鏈接,所以,首先要創建TCP鏈接,通常TCP鏈接的端口號是80。這裏是8080端口
創建鏈接後,客戶機發送一個請求給服務器,請求方式的格式爲:統一資源標識符(URL)、協議版本號,後邊是MIME信息包括請求修飾符、客戶機信息和可內容。
服務器接到請求後,給予相應的響應信息,其格式爲一個狀態行,包括信息的協議版本號、一個成功或錯誤的代碼,後邊是MIME信息包括服務器信息、實體信息和可能的內容。
實體消息是服務器向瀏覽器發送頭信息後,它會發送一個空白行來表示頭信息的發送到此爲結束,接着,它就以Content-Type應答頭信息所描述的格式發送用戶所請求的實際數據
通常狀況下,一旦Web服務器向瀏覽器發送了請求數據,它就要關閉TCP鏈接,而後若是瀏覽器或者服務器在其頭信息加入了這行代碼
Connection:keep-alive
TCP鏈接在發送後將仍然保持打開狀態,因而,瀏覽器能夠繼續經過相同的鏈接發送請求。保持鏈接節省了爲每一個請求創建新鏈接所需的時間,還節約了網絡帶寬。
服務器將響應信息傳給客戶端,響應體中的內容多是一個html頁面,也多是一張圖片,經過輸入流將其讀出,並寫回到顯示器上。其中數據文件中的傳輸無非就是網絡中的封裝與解封裝的過程,而響應消息接收完成後由瀏覽器識別文件中的標籤,而後顯示格式,在而後由BOM的window對象之下的DOM識別動態操做事件渲染到網頁上
請求消息格式
一個完整的http請求消息,包含一個請求行,若干個消息頭(請求頭),換行,實體內容
描述客戶端的請求方式、請求資源的名稱、http協議的版本號。 例如: GET/BOOK/JAVA.HTML HTTP/1.1
get提交和post提交的區別: GET方式: http默認請求方式----get 將表單數據,以"name=value"形式追加到客戶端發送請求的地址欄url路徑後面,二者間用"?"隔開,每個表單的"name=value"間用"&"號隔開。 特色:只適合提交少許信息(瀏覽器對url的長度有限定),而且不太安全(不要提交敏感數據)、提交的數據類型只限於ASCII字符。 POST方式: 將表單數據直接發送(隱藏)到請求消息的請求體中。POST發送的數據不可見。 特色:能夠提交海量信息,相對來講安全一些,提交的數據格式是多樣的(Word、Excel、rar、img)。
|
get:
GET /562f25980001b1b106000338.jpg HTTP/1.1 Host img.mukewang.com User-Agent Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36 Accept image/webp,image/*,*/*;q=0.8 Referer http://www.imooc.com/ Accept-Encoding gzip, deflate, sdch Accept-Language zh-CN,zh;q=0.8
post:
POST / HTTP1.1 Host:www.wrox.com User-Agent:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022) Content-Type:application/x-www-form-urlencoded Content-Length:40 Connection: Keep-Alive name=Professional%20Ajax&publisher=Wiley
第一部分:請求行,第一行明瞭是post請求,以及http1.1版本。
第二部分:請求頭部,第二行至第六行。
第三部分:空行,第七行的空行。
第四部分:請求數據,第八行
url 的格式:
協議://域名或IP+端口+/路徑?參數
(參數就是get請求時的搜索請求的具體內容如 a=1&b=2)
一、Host 請求的web服務器域名地址 二、User-Agent HTTP客戶端運行的瀏覽器類型的詳細信息。經過該頭部信息,web服務器能夠判斷出http請求的客戶端的瀏覽器的類型。 三、Accept 指定客戶端可以接收的內容類型,內容類型的前後次序表示客戶都接收的前後次序 四、Accept-Lanuage 指定HTTP客戶端瀏覽器用來展現返回信息優先選擇的語言 五、Accept-Encoding 指定客戶端瀏覽器能夠支持的web服務器返回內容壓縮編碼類型。表示容許服務器在將輸出內容發送到客戶端之前進行壓縮,以節約帶寬。 而這裏設置的就是客戶端瀏覽器所可以支持的返回壓縮格式。 六、Accept-Charset HTTP客戶端瀏覽器能夠接受的字符編碼集 七、Content-Type 顯示此HTTP請求提交的內容類型。通常只有post提交時才須要設置該屬性 有關Content-Type屬性值有以下兩種編碼類型: (1)「application/x-www-form-urlencoded」: 表單數據向服務器提交時所採用的編碼類型,默認的缺省值就是「application/x-www-form-urlencoded」。 然而,在向服務器發送大量的文本、包含非ASCII字符的文本或二進制數據時這種編碼方式效率很低。 (2)「multipart/form-data」: 在文件上載時,所使用的編碼類型應當是「multipart/form-data」,它既能夠發送文本數據,也支持二進制數據上載。 當提交爲表單數據時,可使用「application/x-www-form-urlencoded」;當提交的是文件時,就須要使用「multipart/form-data」編碼類型。 八、Keep-Alive 表示是否須要持久鏈接。若是web服務器端看到這裏的值爲「Keep-Alive」,或者看到請求使用的是HTTP 1.1(HTTP 1.1默認進行持久鏈接),它就能夠利用持久鏈接的優勢
請求頭和請求體間隔加一行換行符,此換行表示下面是請求體消息
請求體內容:就是指瀏覽器端經過http協議發送給服務器的實體數據。例如:name=dylan&id=110
可參考:菜鳥教程:點此處
HTTP響應也由四個部分組成,分別是:狀態行、消息報頭、空行和響應正文。
例子:
HTTP/1.1 200 OK Date: Fri, 22 May 2009 06:07:21 GMT Content-Type: text/html; charset=UTF-8 <html> <head></head> <body> <!--body goes here--> </body> </html>
第一行爲狀態行,(HTTP/1.1)代表HTTP版本爲1.1版本,狀態碼爲200,狀態消息爲(ok)
第二行和第三行爲消息報頭,
Date:生成響應的日期和時間;Content-Type:指定了MIME類型的HTML(text/html),編碼類型是UTF-8
空行後面的html部分爲響應正文。
協議版本+狀態碼+狀態碼的緣由短語
響應狀態碼:
Server:服務器經過這個頭,告訴瀏覽器服務器的類型
Content-Encoding:告訴瀏覽器,服務器的數據壓縮格式
Content-Length:告訴瀏覽器,回送數據的長度
Content-Type:告訴瀏覽器,回送數據的類型
Last-Modified:告訴瀏覽器當前資源緩存時間
Refresh:告訴瀏覽器,隔多長時間刷新
Content-Disposition:告訴瀏覽器如下載的方式打開數據。例如: context.Response.AddHeader("Content-Disposition","attachment:filename=aa.jpg"); context.Response.WriteFile("aa.jpg");
Transfer-Encoding:告訴瀏覽器,傳送數據的編碼格式
ETag:緩存相關的頭(能夠作到實時更新)
Expries:告訴瀏覽器回送的資源緩存多長時間。若是是-1或者0,表示不緩存
Cache-Control:控制瀏覽器不要緩存數據 no-cache
Pragma:控制瀏覽器不要緩存數據 no-cache
Connection:響應完成後,是否斷開鏈接。 close/Keep-Alive
Date:告訴瀏覽器,服務器響應時間
響應頭和響應體之間有空行,空白行來表示頭信息的發送到此爲結束,接着,它就以Content-Type應答頭信息所描述的格式發送用戶所請求的實際數據
socket服務器
1 import socket 2 3 def handle_request(client): 4 # 服務端接收到的數據 5 request_data = client.recv(1024) 6 print("request_data: ",request_data) 7 8 with open('login.html','rb') as f: 9 data = f.read() 10 # 給客戶端發送的響應消息 11 client.send(b"HTTP/1.1 200 OK\r\nstatus: 200\r\nContent-Type:text/html\r\n\r\n"+data) 12 13 14 def main(): 15 # 建立服務端socket對象 16 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 17 # 綁定服務端IP和端口到套接字 18 sock.bind(('127.0.0.1',8000)) 19 # 服務端等待鏈接的數量限制 20 sock.listen(5) 21 22 while True: 23 print("the server is waiting for client-connection....") 24 # 服務端accept接收的Conn(全雙工管道) 是客戶端傳過來的socket對象 25 connection, address = sock.accept() 26 # 接收到客戶端後的業務處理 27 handle_request(connection) 28 29 # 與客戶端斷開鏈接 30 connection.close() 31 32 if __name__ == '__main__': 33 34 main()
login.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <form action="http://127.0.0.1:8000/" method="post"> 用戶名:<input type="text" name="user"> 密碼:<input type="password" name="pwd"> <input type="submit"> </form> </body> </html>
本文章主要參考有:
以及其餘內容