接上篇,本篇將講一些更加深刻理論的內容。ajax
爲了讓只認識二進制的計算機顯示各類各樣的文字咱們發明了編碼規範,好比常見的GBK、ASCⅡ、Unicode等。編碼規範由三部分組成:字庫表、字符集、編碼方式。數據庫
顯示文字的原理就是:一串二進制數據,經過一種「編碼方式」,分割、轉化成「字符集」中的地址,而後在「字庫表」中找到對應的字符圖形數據,輸出設備依據圖形數據顯示出字。
通常編碼與解碼須要相同的編碼規範才能保證正確,雖然也有Unicode兼容ASCⅡ的狀況,但反過來ASCⅡ就沒法編碼和解碼Unicode。segmentfault
HTTP協議規範裏URL是採用ASCⅡ編碼規範,理論上對於採用Unicode編碼的中文等其餘文字是不支持的,因此若是URL中含有非ASCII字符集的字符(以及保留字,好比&),要對其進行編碼,因而有了「%編碼」規範。瀏覽器
RFC3986文檔規定,Url中只容許包含英文字母(a-zA-Z)、數字(0-9)、-_.~4個特殊字符以及全部保留字符。
對於URL中屬於ASCⅡ字符集的非保留字不作編碼;對URL中的保留字須要取其ASCⅡ內碼,而後加上「%」前綴進行編碼;對於URL中非ASCⅡ字符須要取其Unicode內碼,而後加上「%」前綴進行編碼。緩存
這裏對於「非ASCII字符集的字符」和「保留字」還應該分開說明:安全
http://g.cn/search?a=b
這裏的等於號是結構的一部分因此不須要編碼;http://g.cn/search?a=b%3D
這裏本來是a=b=,這裏的等於號是參數值,非結構的一部分,因此被編碼成「%3D」。常見的認證方式可分爲4種:BASIC認證(基本認證)、DIGEST認證(摘要認證)、SSL客戶端認證、FormBase認證(基於表單認證)。
前兩種是HTTP協議的標準認證方式,但其實如今已經不多使用;後兩種是由客戶端自行實現,通常SSL客戶端認證用於網銀等高安全環境,FormBase認證是如今最經常使用的認證方式。服務器
示意圖以下:(來自MDN)
cookie
爲了彌補BASIC認證存在的弱點,從HTTP/1.1起就有了DIGEST認證。
DIGEST認證一樣使用質詢/響應的方式,但不會像BASIC認證那樣直接發送明文密碼。過程相似於BASIC認證,示意圖參考上面的。網絡
藉由HTTPS的客戶端證書完成認證的方式。憑藉客戶端證書認證,服務器可確認訪問是否來自已登陸的客戶端。session
基於表單的認證方式並非在HTTP協議中定義,是由Web應用程序各自實現。好比session-cookie機制。
在HTTP/1.x裏有多種模型:短鏈接,長鏈接,和HTTP流水線。
HTTP流水線並無瀏覽器支持,已經被HTTP/2.0的多路複用特性所取代,這裏就不詳細討論了。
鏈接的長與短只是相對的概念,並無嚴格意義上規定多久纔算長。
討論HTTP的長鏈接與短鏈接,本質是討論TCP鏈接的複用狀況。
由請求報文頭和響應報文頭裏的Connection
字段決定,值爲close
則爲短鏈接,值爲keep-alive
則爲長鏈接,只有服務器與客戶端協商一直纔會進行長鏈接,而且雙方在任意時刻均可以關閉,彼此都不受影響。
HTTP/1.0中,默認使用的是短鏈接。也就是說,瀏覽器和服務器每進行一次HTTP操做,就創建一次TCP鏈接,結束就中斷。
基礎篇(傳送門)中講到HTTP協議在1.0版本以前的一個特色是「無鏈接」,這個也就是短鏈接,只是在後續版本種變成了可選項。
每次請求都通過」這樣的過程如圖:
HTTP/1.1起,默認使用長鏈接。也就是說,就是隻創建一次TCP鏈接,屢次資源請求都複用該TCP鏈接,完成後再關閉。
每次請求都通過這樣的過程如圖:
長鏈接雖然增長了TCP鏈接的複用率,但實質上仍是基於請求/響應模式的,並不能實現及時更新、或是服務器主動向客戶端發送信息。因而就有了「ajax輪詢」、「ajax長輪詢(Long Poll)」這兩種變通手段。
這兩種變通手段都是以消耗大量服務器資源爲代價,所以爲了根本解決這個問題,後來發展出了WebSocket協議,這就是後話了。
代理扮演的是「中間人」角色,對於鏈接到它的客戶端來講,它是服務端;對於要鏈接的服務端來講,它是客戶端。它就負責在兩端之間來回傳送HTTP報文。
示意圖以下:
網關扮演的是「協議轉換器」角色,能夠做爲某種翻譯器使用,它抽象出了一種可以到達資源的方法。網關是資源和應用程序之間的粘合劑。
代理與網關的區別:代理是轉發相同協議的數據,網關是轉換不一樣協議的數據。
示意圖以下:
指客戶端和服務器就響應的資源內容進行交涉,而後提供給客戶端最爲合適的資源。內容協商會以響應資源的語言,字符集,編碼方式等做爲判斷的基準。
客戶端經過請求報文頭傳遞告訴服務器支持狀況,而且能夠帶有近似匹配的優先級,服務器迴應的響應報文頭裏進行確認,就完成了內容協商。
字段名 | 說明文字 |
---|---|
Accept | 告訴服務器本身能接受的媒體類型 |
Accept-Language | 能接受的語言 |
Accept-Charset | 能接受的字符集(如unicode) |
Accept-Encoding | 能接受的編碼方式(如utf-8) |
字段名 | 說明文字 |
---|---|
Content-Type | 對應Accept |
Content-Language | 對應Accept-Language |
Content-Type | 對應Accept-Charset |
Content-Encoding | 對應Accept-Encoding |
經過在報文頭裏兩個參數實現的,客戶端發請求時對應的是Range,服務器響應時對應的是Content-Range 。
Range用於請求頭中,指定第一個字節的位置和最後一個字節的位置。
格式爲:
Range:(unit=first byte pos) - \[last byte pos\]
HTTP/1.1 200 Ok(不使用斷點續傳方式)
HTTP/1.1 206 Partial Content(使用斷點續傳方式)
Content-Range用於響應頭中,在發出帶Range的請求後,服務器會在Content-Range頭部返回當前接受的範圍和文件總大小。
格式爲:
Content-Range:bytes(unit first byte pos) - \[last byte pos\]/\[entity length\](文件總大小)
斷點續傳是被動的增量下載,多線程是主動的分片下載,但使用都是Range模式。