整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          HTTP Range 請求總結

          HTTP Range 請求總結

          TTP Range 請求總結

          HTTP range 請求允許我們從服務器上只發送HTTP消息的一部分到客戶端。這樣的部分請求對于大型媒體、具有中斷和恢復下載進度的下載文件請求很有幫助。

          檢查服務器是否支持 HTTP Range 請求

          在進行HTTP range 請求之前,先檢查服務器是否支持部分請求

          如果請求一個資源時, HTTP響應中出現如下所示的 'Accept-Ranges', 且其值不是none, 那么服務器支持范圍請求。

          curl -I http://i.imgur.com/z4d4kWk.jpg
          
          HTTP/1.1 200 OK
          ...
          Accept-Ranges: bytes
          Content-Length: 146515

          在如上響應中,Accept-Ranges: bytes 代表可以使用字節作為單位來定義請求范圍。這里的 Response Headers中的 Content-Length: 146515 則代表該資源的完整大小。

          如果站點響應中未返回 Accept-Ranges 響應頭,或者其值為none,那么這意味著server不支持HTTP range請求。

          給服務器發HTTP Range請求

          一、單范圍請求

          我們可以對一個資源發起單個范圍請求:

          curl http://i.imgur.com/z4d4kWk.jpg -i -H "Range: bytes=0-1023"

          發出的請求如下:

          GET /z4d4kWk.jpg HTTP/1.1 Host: i.imgur.com Range: bytes=0-1023

          正常情況下 server 返回 206 部分內容響應:

          HTTP/1.1 206 Partial Content Content-Range: bytes 0-1023/146515 Content-Length: 1024 ... (binary content)

          這次并非檢查server是否支持range請求,故Content-Length表示的是現在請求的范圍大小,而Content-Range則表示的是這部分消息在完整資源中的位置。

          二、多范圍請求

          curl http://www.example.com -i -H "Range: bytes=0-50, 100-150"

          用逗號隔開多個范圍,即可同時請求多部分資源。

          響應如下:

          HTTP/1.1 206 Partial Content Content-Type: multipart/byteranges; boundary=3d6b6a416f9b5 Content-Length: 282 --3d6b6a416f9b5 Content-Type: text/html Content-Range: bytes 0-50/1270

          該響應有:

          • 206部分響應碼:
          • Content-Type: multipart/byteranges;boundary=3d6b6a416f9b5——>表示遵循多部分 byterange

          每個部分包含自己的Content-Type 和 Content-Range

          三、條件范圍請求

          當繼續請求更多資源時,你需要確保被存儲的資源在上一幀收到后沒有被改變。

          If-Range HTTP請求創建了一個帶條件的range HTTP請求,如果條件得到滿足,range請求將會被發出,server 發回帶有適當正文的206 partial content 應答,如果條件不滿足則返回完整資源,并顯示200 OK狀態。這個頭可以與Last-Modified 驗證程序,或者與 ETag 一起使用。

          If-Range: Wed, 21 Oct 2015 07:28:00 GMT

          HTTP Range 請求響應

          在處理HTTP Range 請求時,有三個相關的狀態:

          • 206 Partial Content——> HTTP Range 請求成功
          • 416 Requested Range Not Satisfiable status.——> HTTP Range 請求超出界限
          • 200 OK——> 不支持范圍請求

          與分塊相比

          Transfer-Encoding 請求頭允許分塊編碼,這在服務器給客戶端發送大量的數據,且響應總大小直到請求結束才能確定時很有用,如果服務器直接發送數據給客戶端而不緩存響應,或者確定具體響應大小的話,會產生延遲。HTTP Range 請求和分塊是兼容的,一起用或者不一起用均可。

          天這篇文章和大家聊一聊如何做到只請求資源的一部分,這里需要用到幾個http頭——range、if-range、content-range、accept-range。

          Range頭信息介紹

          Range主要用來設置獲取數據的范圍,格式如下:

          Range: <unit>=<range-start>-<range-end>
          Range: <unit>=<range-start>-<range-end>, <range-start>-<range-end>, <range-start>-<range-end>
        1. <unit> 類型,一般來說是bytes;
        2. <range-start> 表示范圍的起始值,一般是數字,如果不是數字就看服務端邏輯如何處理;
        3. <range-end> 表示范圍的結束值。這個值是可選的,如果不存在,表示此范圍一直延伸到文檔結束,如果非數字,同上。
        4. 如: 獲取 0-10字節的數據和15到結尾的數據

          Range: bytes=0-10,15-

          If-Range主要用來判斷是否滿足范圍請求的條件,舉個例子,假設昨天你用迅雷下載了一部電影但是沒有下載完,今天你要接著下載,當再次下載時客戶端就需要和服務器驗證這部電影的資源內容有沒有發生變化,If-Range在這里就是做驗證使用的 。

          Content-Range表示響應數據的內容范圍,語法格式如下:

          Content-Range: <unit> <range-start>-<range-end>/<size>
          Content-Range: <unit> <range-start>-<range-end>/*
          Content-Range: <unit> */<size>
          • <unit> 類型,一般來說是bytes;
          • <range-start> 區間的起始值;
          • <range-end> 區間的結束值;
          • <size> 整個文件的大小(如果大小未知則用 "*" 表示)

          例如:

          Content-Range: bytes?10-15/22

          Accept-Ranges用于服務器響應,告訴瀏覽器是否支持Range,

          語法:

          Accept-Ranges: bytes
          Accept-Ranges: none
          • none不支持任何范圍請求單位,由于其等同于沒有返回此頭部,因此很少使用。不過一些瀏覽器,比如IE9,會依據該頭部去禁用或者移除下載管理器的暫停按鈕;
          • bytes 一般情況

          代碼實現

          上面介紹了幾個頭信息的概念,下面我們用代碼實現一下,大概流程如下:

          圖1

          我們還是以中間件的方式去實現。

          圖2

          如圖2,我們通過range頭獲取請求的范圍信息,如果類型合法,我們還需要處理范圍數據,處理方式和處理url的query一樣,在處理的過程中我們需要對不合法的范圍進行糾正和過濾。如果類型不合法,我們就正常返回整個內容。

          對于range范圍內重疊和相鄰的區域可以做一次合并,例如:

          bytes=50-55,0-10,5-10,56-60,可以合并為[{start: 0, end: 10},{start: 50, end: 60}]。

          圖3

          如圖3,如果range范圍無效,我們返回狀態碼416,告訴客戶端range是無效的,不滿足要求。

          圖4

          如圖4,如果range范圍校驗也沒問題,我們還需要通過if-range提供的信息與etag或者Last-Modified做對比(對比二選一)。

          • 如果if-range沒有值,可以認為是無條件的,返回true;
          • 如果和etag有一致的地方,證明資源未變,返回true,可以繼續部分請求;
          • 如果給的時間條件大于修改的時間,證明資源也未變,可以繼續部分請求(大于還是小于,時間的意義可以自己定);

          如果不滿足if-range條件,繼續走正常返回資源的邏輯,如果滿足那就開始返回部分資源。

          圖5

          如圖5,設置了狀態為206,這是http標識部分內容返回的狀態,另外還設置了accept-range和content-type。此處我們使用stream對內容進行分片,這里只返回了一段范圍的內容。

          對于多段請求,也是可以實現的,如下:

          圖6

          需要把content-type設置成multipart/byteranges; boundary=分隔符,這樣的話就可以分片下載了。

          總結

          這篇文章主要介紹了range頭相關的使用方法,內容還是蠻多的。本文的代碼實現沒那么全,主要講了一下原理及流程,小伙伴們如果需要使用可以再打磨一下。

          TTP的定義

          Hypertext Transfer Protocol,超文本傳輸協議,和HTML(Hypertext MarkupLanguage 超文本標記語言)一起誕生的,用于在網絡上請求和傳輸HTML內容。

          超文本,也就是擴展文本,指的是HTML中可以有鏈向別的文本的鏈接(hyperlink)。

          HTTP的工作方式

          瀏覽器:

          用戶輸入地址回車或點擊鏈接->瀏覽器拼裝HTTP報文并發送請求給服務器->服務器處理請求后發送響應報文給瀏覽器->瀏覽器解析響應報文并使用渲染引擎顯示到界面

          手機App:

          用戶點擊或界面自動觸發聯網需求->Android代碼調用拼裝HTTP報文并發送請求到服務器->服務器處理請求后發送響應報文給手機->Android代碼處理響應報文并作出相應處理(如儲存數據、加工數據、顯示數據到界面)

          URL和HTTP報文

          URL格式

          三部分:協議類型、服務器地址(和端口號)、路徑(Path)

          協議類型://服務器地址[:端口號]路徑

          例如:http://toutiao.com/users?gender=male

          報文格式

          請求報文

          響應報文

          Request Method 請求方法

          GET

          • 用于獲取資源
          • 對服務器數據不進行修改
          • 不發送Body

          對應Android Retrofit的代碼

          POST

          • 用于增加或修改資源
          • 發送給服務器的內容寫在Body里面

          對應Retrofit的代碼:

          PUT

          • 用戶修改資源
          • 發送給服務器的內容寫在Body

          對應Retrofit的代碼:

          DELETE

          • 用戶刪除資源
          • 不發送Body

          HEAD

          • 和GET使用方法完全相同
          • 和GET唯一區別在于,返回的響應中沒有Body

          Status Code狀態碼

          三位數字,用戶對響應結果做出類型化描述(如獲取成功,內容未找到)。

          • 1xx:臨時性消息。如:100(繼續發送)、101(正在切換協議)
          • 2xx:成功。最典型的是 200(OK)、201(創建成功)。
          • 3xx:重定向。如 301(永久移動)、302(暫時移動)、304(內容未改變)。
          • 4xx:客戶端錯誤。如400(客戶端請求錯誤)、401(認證失敗)、403(被禁止)、404(找不到內容)。
          • 5xx:服務器錯誤。如 500(服務器內部錯誤)。

          Header 首部

          作用:HTTP消息的metadata。

          Host

          目標主機。注意:不是在網絡上用于尋址的,而是在目標服務器上用于定位子服務器的。

          Content-Type

          指定Body的類型,主要有四類:

          1. text/html

          請求Web頁面是返回響應的類型,Body中返回html文本。格式如下:


          1. x-www-form-urlencoded

          Web頁面純文本表單的提交方式。

          格式如下:

          對應Retrofit的代碼

          1. multipart/form-data

          Web頁面含有二進制文件時的提交方式。

          格式如下:

          對應Retrofit的代碼:

          1. application/json,image/jpeg,application/zip...

          單項內容(文本或非文本都可以),用于Web Api的響應或者POST/PUT的請求

          請求中提交JSON

          對應Retrofit的代碼

          響應中返回JSON


          請求中提交二進制內容

          對應Retrofit的代碼

          相應中返回二進制內容

          Content-Length

          指定Body的長度(字節)。

          Transfer:chunked(分塊傳輸編碼Chunked Transfer Encoding)

          用于當響應發起時,內容長度還沒能確定的情況下。和Content-Length不同時使用。用途是盡早給出響應,減少用戶等待。

          格式:

          Location

          指定重定向的目標URL

          User-Agent

          用戶代理,即是誰實際發送請求、接受響應的,例如手機瀏覽器、某款手機App。

          Range/Accept-Range

          按范圍取數據

          Accept-Range:bytes響應報文中出現,表示服務器支持按字節來取范圍數據

          Range:bytes=<start>-<end>請求報文中出現,表示要取哪段數據

          Content-Range:<start>-<end>/total響應報文中出現,表示發送的是哪段數據

          作用:斷點續傳、多線程下載。

          其他Headers

          • Accept:客戶端能接受的數據類型。如text/html
          • Accept-Charset:客戶端接收的字符集。如utf-8
          • Accept-Encoding:客戶端接受的壓縮編碼。如gzip
          • Content-Encoding:壓縮類型。如gzip

          Cache

          作用:在客戶端或中間網絡節點緩存數據,降低從服務器數據的頻率,以提高網絡性能。

          REST

          REST的定義眾說紛紜,沒有統一答案。

          個人認為:REST HTTP即正確使用HTTP。包括:

          • 使用資源的格式來定義URL
          • 規范地使用method來定義網絡請求操作
          • 規范地使用status code來表示響應狀態
          • 其他符合HTTP規范的設計準則

          題目練習

          1.【單選題】用戶在瀏覽器地址欄輸入地址后回車,一段時間后瀏覽器顯示出頁面,這背后發生了什么?

          A. 瀏覽器拼裝 HTTP 報文并向服務器請求 -> 服務器處理請求并返回響應報文 -> 瀏覽器接收到響應報文后處理并使用渲染引擎來渲染出界面

          B. 瀏覽器把地址欄的 URL 發送給服務器 -> 服務器把 URL 對對應的頁面圖片文件發回給瀏覽器 -> 瀏覽器接收到圖片后顯示出來

          2.【單選題】一個 URL 如 http://api.qq.com/user/1 中,對于「HTTP 組裝報文」來說可以拆成哪幾部分

          A. ① 【http:】-> 協議類型 ② 【//api.qq.com/user/1】-> 路徑

          B. ① 【http:】-> 協議類型 ② 【//api.qq.com】-> 服務器地址 ③ 【/user/1】-> 路徑

          C. ① 【http:】-> 協議類型 ② 【//api.qq.com/user/】-> 路徑 ③ 【1】-> 文件名

          3.【單選題】HTTP 的請求報文分為哪幾部分?

          A. 請求行、path、Headers、Body

          B. 請求行、Headers、Body

          C. 請求行、方法、Host、Body

          4.【單選題】請求行由哪三部分組成?

          A. method、path、HTTP 版本

          B. method、path、Host

          C. method、服務器地址、path

          5.【單選題】HTTP 的響應報文分為哪幾部分?

          A. 響應頭、響應碼、響應信息

          B. 狀態行、響應頭、Headers、Body

          C. 狀態行、Headers、Body

          6.【單選題】響應報文的狀態行由哪三部分組成?

          A. HTTP 版本、API 版本、狀態碼

          B. HTTP 版本、狀態碼、狀態信息

          C. HTTP 版本、Body 類型、狀態碼

          7.【多選題】以下哪幾項符合 GET 方法?

          A. 用于獲取資源A

          B. 用于增加或修改資源

          C. 僅用于修改資源

          D. 用于刪除資源

          E. 冪等(即反復調用多次時會得到相同的結果)E. 冪等(即反復調用多次時會得到相同的結果)

          F. 請求報文中包含 BodyF. 請求報文中包含 Body

          8.【多選題】以下哪幾項符合 POST 方法?

          A. 用于獲取資源A. 用于獲取資源

          B. 用于增加或修改資源B. 用于增加或修改資源

          C. 僅用于修改資源C. 僅用于修改資源

          D. 用于刪除資源D. 用于刪除資源

          E. 冪等(即反復調用多次時會得到相同的結果)E. 冪等(即反復調用多次時會得到相同的結果)

          F. 請求報文中包含 BodyF. 請求報文中包含 Body

          9.【多選題】以下哪幾項符合 PUT 方法?

          A. 用于獲取資源A. 用于獲取資源

          B. 用于增加或修改資源B. 用于增加或修改資源

          C. 僅用于修改資源C. 僅用于修改資源

          D. 用于刪除資源D. 用于刪除資源

          E. 冪等(即反復調用多次時會得到相同的結果)E. 冪等(即反復調用多次時會得到相同的結果)

          F. 請求報文中包含 BodyF. 請求報文中包含 Body

          10.【多選題】以下哪幾項符合 DELETE 方法?

          A. 用于獲取資源A. 用于獲取資源

          B. 用于增加或修改資源B. 用于增加或修改資源

          C. 僅用于修改資源C. 僅用于修改資源

          D. 用于刪除資源D. 用于刪除資源

          E. 冪等(即反復調用多次時會得到相同的結果)E. 冪等(即反復調用多次時會得到相同的結果)

          F. 請求報文中包含 BodyF. 請求報文中包含 Body

          11.【單選題】Host 這個 Header 的作用是?

          A. 在網絡上尋址目標主機的 IP,并在找到目標主機后確認主機域名和端口

          B. 僅用于尋址目標主機的 IP

          C. 僅用于找到目標主機后確認主機域名和端口

          12.【單選題】Content-Type 為 x-www-form-urlencoded 時,請求報文中 Body 的格式為以下哪種形式?

          A. Encoded URL,即 name1=value1&name2=value2 的形式

          B. 分多個部分傳輸每部分內容的形式,使用 boundary 對它們進行分隔

          C. JSON 形式,如 {"name1":value1,"name2":value2}

          13.【單選題】Content-Type 為 multipart/form-data 時,請求報文中 Body 的格式為以下哪種形式?

          A. Encoded URL,即 name1=value1&name2=value2 的形式

          B. 分多個部分傳輸每部分內容的形式,使用 boundary 對它們進行分隔

          C. JSON 形式,如 {"name1":value1,"name2":value2}

          14.【單選題】Content-Type 為 application/json 時,請求報文中 Body 的格式為以下哪種形式?

          A. Encoded URL,即 name1=value1&name2=value2 的形式

          B. 分多個部分傳輸每部分內容的形式,使用 boundary 對它們進行分隔

          C. JSON 形式,如 {"name1":value1,"name2":value2}

          答案:ABBACBABBDAABCB


          主站蜘蛛池模板: 精品乱人伦一区二区| 亚洲AV永久无码精品一区二区国产| 国产午夜精品片一区二区三区| 日韩免费观看一区| 国产乱人伦精品一区二区 | 精品国产一区二区三区久| 精品女同一区二区三区免费播放| 精品国产一区二区三区香蕉| 波多野结衣精品一区二区三区 | 日韩精品一区二三区中文| 国产视频福利一区| 亚洲制服丝袜一区二区三区| 中文字幕人妻无码一区二区三区| 一区二区在线视频免费观看| 中文字幕无线码一区2020青青| 污污内射在线观看一区二区少妇| 久久久久一区二区三区| 小泽玛丽无码视频一区| 人妻夜夜爽天天爽一区| 精品免费国产一区二区| 日韩在线一区二区| 亚洲av无码一区二区三区人妖| 亚洲欧美日韩中文字幕在线一区 | 国产一区二区免费在线| 亚洲一区二区三区乱码在线欧洲| 91在线看片一区国产| 天堂资源中文最新版在线一区| 国产AV午夜精品一区二区三区| 久久99精品国产一区二区三区| 在线观看国产区亚洲一区成人| 亚洲一区视频在线播放| AV无码精品一区二区三区宅噜噜| 国产乱码精品一区二区三区中文| 无码AV中文一区二区三区| 久久久国产精品亚洲一区| 日韩一区二区在线观看视频| 国产精品视频一区二区三区| 在线免费视频一区二区| 国产精品成人一区二区| 久久久久人妻精品一区蜜桃| 精品国产一区二区三区四区|