<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ## HTTP 協議 HTTP 協議是互聯網的基礎協議,也是網頁開發的必備知識,最新版本 HTTP/2 更是讓它成為技術熱點。 本文介紹 HTTP 協議的歷史演變和設計思路。 ![客戶端服務端通信](https://box.kancloud.cn/b4678d69bfe618eaa1ea5e12b414f5ad_478x180.jpg) ### 一、HTTP/0.9 HTTP 是基于 TCP/IP 協議的應用層協議。它不涉及數據包(packet)傳輸,主要規定了客戶端和服務器之間的通信格式,默認使用80端口。 最早版本是1991年發布的0.9版。該版本極其簡單,只有一個命令GET。 GET /index.html 上面命令表示,TCP 連接(connection)建立后,客戶端向服務器請求(request)網頁 index.html。 協議規定,服務器只能回應HTML格式的字符串,不能回應別的格式。 <html> <body>Hello World</body> </html> 服務器發送完畢,就關閉 TCP 連接。 ### 二、HTTP/1.0 **2.1 簡介** 1996年5月,HTTP/1.0 版本發布,內容大大增加。 首先,任何格式的內容都可以發送。這使得互聯網不僅可以傳輸文字,還能傳輸圖像、視頻、二進制文件。這為互聯網的大發展奠定了基礎。 其次,除了 GET 命令,還引入了 POST 命令和 HEAD 命令,豐富了瀏覽器與服務器的互動手段。 再次,HTTP請求和回應的格式也變了。除了數據部分,每次通信都必須包括頭信息(HTTP header),用來描述一些元數據。 其他的新增功能還包括狀態碼(status code)、多字符集支持、多部分發送(multi-part type)、權限(authorization)、緩存(cache)、內容編碼(content encoding)等。 **2.2 請求格式** 下面是一個1.0版的 HTTP 請求的例子。 GET / HTTP/1.0 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) Accept: */* 可以看到,這個格式與0.9版有很大變化。 第一行是請求命令,必須在尾部添加協議版本(HTTP/1.0)。后面就是多行頭信息,描述客戶端的情況。 **2.3 回應格式** 服務器的回應如下: HTTP/1.0 200 OK Content-Type: text/plain Content-Length: 137582 Expires: Thu, 05 Dec 1997 16:00:00 GMT Last-Modified: Wed, 5 August 1996 15:55:28 GMT Server: Apache 0.84 <html> <body>Hello World</body> </html> 回應的格式是"頭信息 + 一個空行(\r\n) + 數據"。其中,第一行是"協議版本 + 狀態碼(status code) + 狀態描述"。 常見的狀態碼: * 200 OK - 服務器成功返回用戶請求的數據,該操作是冪等的(Idempotent)。 * 201 Created - 用戶新建或修改數據成功。 * 202 Accepted - 服務器已接受請求,但尚未處理。 * 204 No Content - 用戶刪除數據成功。 * 301 Moved Permanently - 被請求的資源已永久移動到新位置。 * 302 Move Temporarily - 請求的資源臨時從不同的 URI 響應請求。 * 400 Bad Request - 用戶發出的請求有錯誤,服務器沒有進行新建或修改數據的操作,該操作是冪等的。 * 401 Unauthorized - 表示用戶沒有權限(令牌、用戶名、密碼錯誤)。 * 403 Forbidden - 表示用戶得到授權(與401錯誤相對),但是訪問是被禁止的。 * 404 Not Found - 用戶發出的請求針對的是不存在的記錄,服務器沒有進行操作,該操作是冪等的。 * 406 Not Acceptable - 用戶請求的格式不可得(比如用戶請求JSON格式,但是只有XML格式)。 * 500 Internal Server Error - 服務器發生錯誤,用戶將無法判斷發出的請求是否成功。 * 503 Service Unavailable - 由于臨時的服務器維護或者過載,服務器當前無法處理請求。 **2.4 Content-Type 字段** 關于字符的編碼,1.0 版規定,頭信息必須是 ASCII 碼,后面的數據可以是任何格式。因此,服務器回應的時候,必須告訴客戶端,數據是什么格式,這就是Content-Type字段的作用。 下面是一些常見的Content-Type字段的值: text/plain text/html text/css image/jpeg image/png image/svg+xml audio/mp4 video/mp4 application/javascript application/pdf application/zip application/atom+xml 這些數據類型總稱為 MIME type,每個值包括一級類型和二級類型,之間用斜杠分隔。 除了預定義的類型,廠商也可以自定義類型。 application/vnd.debian.binary-package 上面的類型表明,發送的是 Debian 系統的二進制數據包。 MIME type 還可以在尾部使用分號,添加參數。 Content-Type: text/html; charset=utf-8 上面的類型表明,發送的是網頁,而且編碼是 UTF-8。 客戶端請求的時候,可以使用Accept字段聲明自己可以接受哪些數據格式。 Accept: */* 上面代碼中,客戶端聲明自己可以接受任何格式的數據。 MIME type 不僅用在 HTTP 協議,還可以用在其他地方,比如 HTML 網頁。 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> **2.5 Content-Encoding 字段** 由于發送的數據可以是任何格式,因此可以把數據壓縮后再發送。Content-Encoding 字段說明數據的壓縮方法。 Content-Encoding: gzip Content-Encoding: compress Content-Encoding: deflate 客戶端在請求時,用 Accept-Encoding 字段說明自己可以接受哪些壓縮方法。 Accept-Encoding: gzip, deflate **2.6 缺點** HTTP/1.0 版的主要缺點是,每個TCP連接只能發送一個請求。發送數據完畢,連接就關閉,如果還要請求其他資源,就必須再新建一個連接。 TCP 連接的新建成本很高,因為需要客戶端和服務器三次握手,并且開始時發送速率較慢(slow start)。所以,HTTP 1.0版本的性能比較差。隨著網頁加載的外部資源越來越多,這個問題就愈發突出了。 為了解決這個問題,有些瀏覽器在請求時,用了一個非標準的Connection字段。 Connection: keep-alive 這個字段要求服務器不要關閉TCP連接,以便其他請求復用。服務器同樣回應這個字段。 Connection: keep-alive 一個可以復用的 TCP 連接就建立了,直到客戶端或服務器主動關閉連接。但是,這不是標準字段,不同實現的行為可能不一致,因此不是根本的解決辦法。 ### 三、HTTP/1.1 1997年1月,HTTP/1.1 版本發布,只比 1.0版本晚了半年。它進一步完善了 HTTP 協議,一直用到了20年后的今天,直到現在還是最流行的版本。 **3.1 持久連接** 1.1 版的最大變化,就是引入了持久連接(persistent connection),即TCP連接默認不關閉,可以被多個請求復用,不用聲明Connection: keep-alive。 客戶端和服務器發現對方一段時間沒有活動,就可以主動關閉連接。不過,規范的做法是,客戶端在最后一個請求時,發送Connection: close,明確要求服務器關閉TCP連接。 Connection: close 目前,對于同一個域名,大多數瀏覽器允許同時建立6個持久連接。 **3.2 管道機制** 1.1 版還引入了管道機制(pipelining),即在同一個 TCP 連接里面,客戶端可以同時發送多個請求。這樣就進一步改進了 HTTP 協議的效率。 舉例來說,客戶端需要請求兩個資源。以前的做法是,在同一個 TCP 連接里面,先發送 A 請求,然后等待服務器做出回應,收到后再發出 B 請求。管道機制則是允許瀏覽器同時發出 A 請求和 B 請求,但是服務器還是按照順序,先回應 A 請求,完成后再回應 B 請求。 **3.3 Content-Length 字段** 一個 TCP 連接現在可以傳送多個回應,勢必就要有一種機制,區分數據包是屬于哪一個回應的。這就是 Content-length 字段的作用,聲明本次回應的數據長度。 Content-Length: 3495 上面代碼告訴瀏覽器,本次回應的長度是3495個字節,后面的字節就屬于下一個回應了。 在1.0版中,Content-Length 字段不是必需的,因為瀏覽器發現服務器關閉了 TCP 連接,就表明收到的數據包已經全了。 **3.4 分塊傳輸編碼** 使用 Content-Length 字段的前提條件是,服務器發送回應之前,必須知道回應的數據長度。 對于一些很耗時的動態操作來說,這意味著,服務器要等到所有操作完成,才能發送數據,顯然這樣的效率不高。更好的處理方法是,產生一塊數據,就發送一塊,采用"流模式"(stream)取代"緩存模式"(buffer)。 因此,1.1版規定可以不使用 Content-Length 字段,而使用"分塊傳輸編碼"(chunked transfer encoding)。只要請求或回應的頭信息有 Transfer-Encoding 字段,就表明回應將由數量未定的數據塊組成。 Transfer-Encoding: chunked 每個非空的數據塊之前,會有一個16進制的數值,表示這個塊的長度。最后是一個大小為0的塊,就表示本次回應的數據發送完了。下面是一個例子。 HTTP/1.1 200 OK Content-Type: text/plain Transfer-Encoding: chunked 25 This is the data in the first chunk 1C and this is the second one 3 con 8 sequence 0 **3.5 其他功能** 1.1版還新增了許多動詞方法:PUT、PATCH、HEAD、 OPTIONS、DELETE。 另外,客戶端請求的頭信息新增了Host字段,用來指定服務器的域名。 Host: www.example.com 有了 Host 字段,就可以將請求發往同一臺服務器上的不同網站,為虛擬主機的興起打下了基礎。 **3.6 缺點** 雖然1.1版允許復用TCP連接,但是同一個TCP連接里面,所有的數據通信是按次序進行的。服務器只有處理完一個回應,才會進行下一個回應。要是前面的回應特別慢,后面就會有許多請求排隊等著。這稱為"隊頭堵塞"(Head-of-line blocking)。 為了避免這個問題,只有兩種方法:一是減少請求數,二是同時多開持久連接。這導致了很多的網頁優化技巧,比如合并腳本和樣式表、將圖片嵌入CSS代碼、域名分片(domain sharding)等等。如果HTTP協議設計得更好一些,這些額外的工作是可以避免的。 ### 四、SPDY 協議 2009年,谷歌公開了自行研發的 SPDY 協議,主要解決 HTTP/1.1 效率不高的問題。 這個協議在Chrome瀏覽器上證明可行以后,就被當作 HTTP/2 的基礎,主要特性都在 HTTP/2 之中得到繼承。 ### 五、HTTP/2 2015年,HTTP/2 發布。它不叫 HTTP/2.0,是因為標準委員會不打算再發布子版本了,下一個新版本將是 HTTP/3。 **5.1 二進制協議** HTTP/1.1 版的頭信息肯定是文本(ASCII編碼),數據體可以是文本,也可以是二進制。HTTP/2 則是一個徹底的二進制協議,頭信息和數據體都是二進制,并且統稱為"幀"(frame):頭信息幀和數據幀。 二進制協議的一個好處是,可以定義額外的幀。HTTP/2 定義了近十種幀,為將來的高級應用打好了基礎。如果使用文本實現這種功能,解析數據將會變得非常麻煩,二進制解析則方便得多。 **5.2 多工** HTTP/2 復用 TCP 連接,在一個連接里,客戶端和瀏覽器都可以同時發送多個請求或回應,而且不用按照順序一一對應,這樣就避免了"隊頭堵塞"。 舉例來說,在一個 TCP 連接里面,服務器同時收到了A請求和B請求,于是先回應A請求,結果發現處理過程非常耗時,于是就發送A請求已經處理好的部分, 接著回應B請求,完成后,再發送A請求剩下的部分。 這樣雙向的、實時的通信,就叫做多工(Multiplexing)。 **5.3 數據流** 因為 HTTP/2 的數據包是不按順序發送的,同一個連接里面連續的數據包,可能屬于不同的回應。因此,必須要對數據包做標記,指出它屬于哪個回應。 HTTP/2 將每個請求或回應的所有數據包,稱為一個數據流(stream)。每個數據流都有一個獨一無二的編號。數據包發送的時候,都必須標記數據流 ID,用來區分它屬于哪個數據流。另外還規定,客戶端發出的數據流,ID 一律為奇數,服務器發出的,ID 為偶數。 數據流發送到一半的時候,客戶端和服務器都可以發送信號(RST_STREAM幀),取消這個數據流。1.1版取消數據流的唯一方法,就是關閉TCP連接。這就是說,HTTP/2 可以取消某一次請求,同時保證 TCP 連接還打開著,可以被其他請求使用。 客戶端還可以指定數據流的優先級。優先級越高,服務器就會越早回應。 **5.4 頭信息壓縮** HTTP 協議不帶有狀態,每次請求都必須附上所有信息。所以,請求的很多字段都是重復的,比如 Cookie 和 User Agent,一模一樣的內容,每次請求都必須附帶,這會浪費很多帶寬,也影響速度。 HTTP/2 對這一點做了優化,引入了頭信息壓縮機制(header compression)。一方面,頭信息使用 gzip 或 compress 壓縮后再發送;另一方面,客戶端和服務器同時維護一張頭信息表,所有字段都會存入這個表,生成一個索引號,以后就不發送同樣字段了,只發送索引號,這樣就提高速度了。 **5.5 服務器推送** HTTP/2 允許服務器未經請求,主動向客戶端發送資源,這叫做服務器推送(server push)。 常見場景是客戶端請求一個網頁,這個網頁里面包含很多靜態資源。正常情況下,客戶端必須收到網頁后,解析 HTML 源碼,發現有靜態資源,再發出靜態資源請求。其實,服務器可以預期到客戶端請求網頁后,很可能會再請求靜態資源,所以就主動把這些靜態資源隨著網頁一起發給客戶端了。 參考鏈接:[HTTP協議入門](http://www.ruanyifeng.com/blog/2016/08/http.html) BY 阮一峰
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看