<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>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                ## **斷點續傳** 什么是斷點續傳? 答:從那個點點斷開繼續傳。。。 額,看起來也沒毛病... 再問一遍,什么是斷點續傳? 答: > 斷點續傳就是從文件上次中斷的地方開始重新下載或上傳,當下載或上傳文件的時候,如果沒有實現斷點續傳功能,那么每次出現異常或者用戶主動的暫停,都會去重頭下載,這樣很浪費時間。所以斷點續傳的功能就應運而生了。要實現斷點續傳的功能,需要客戶端記錄下當前的下載或上傳進度,并在需要續傳的時候通知服務端本次需要下載或上傳的內容片段。 > 說起到斷點續傳,他的關鍵點是什么? * 如何告知服務器,從指定的位置下載 * 如何知道客戶端想要的指定位置是多少 其實,很簡單,并不需要我們去寫一些什么東西。HTTP協議本身就支持斷點續傳了。只要我們通過方式告訴服務器,從制定位置開始下載就可以了。 來來來,http協議搞起來~~~~~~ 先來提問一下昂,說到http想到了什么??? (在線投骰子?還是誰能**~~自告奮勇~~**???) ``` /** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * **/ ``` ## **Range & Content-Length & Content-Range & If-Range** 這些都是 HTTP 包中 Header 頭部的一些字段信息,其中 Range 和 If-Range 是請求頭中的字段,Content-Length 和 Content-Range 是響應頭中的字段。 ### **Range** 當請求頭中出現 Range 字段時,表示告知服務端,客戶端下載該文件想要從指定的位置開始下載,至于 Range 字段屬性值的格式有以下幾種: | 格式 | 含義 | | --- | --- | | Range:bytes=0-500 | 表示下載從0到500字節的文件,即頭500個字節 | | Range:bytes=501-1000 | 表示下載從500到1000這部分的文件,單位字節 | | Range:bytes=-500 | 表示下載最后的500個字節 | | Range:bytes=500- | 表示下載從500開始到文件結束這部分的內容 | 當 app 想實現縮短大文件的下載耗時,可以開啟多個下載線程,每個線程只負責文件的一部分下載,當所有線程下載結束后,將每個線程下載的文件按順序拼接成一個完整的文件,這樣就可以達到縮短下載大文件的耗時目的了。 那么就可以使用`Range:bytes=501-1000`這種格式了,每個線程在各自的請求頭字段中,以這種格式加入相對應的信息即可達到目的了。 ***** 如果 app 想實現斷點續傳,文件下載到一半被迫中斷,下次啟動還可以繼續接著上次進度下載時,那么此時可以使用 `Range:bytes=500-` 這種格式了,只要先獲取本地那份文件目前的大小,通過在請求頭中加入 Range 字段信息即可。 #### **Content-Length** Content-Length 字段出現在響應頭中,用于告知客戶端此次下載的文件大小。 客戶端需要實現下載進度實時更新時,需要知道文件的總大小和目前下載的大小。 想要知道文件總大小? Content-Length中的字段就好 如果想要實現多線程同時分段下載大文件時,在下載前會發送一個不需要攜帶body信息請求,用于先獲取響應頭中的Content-Length字段 > * 如果這條鏈接是一次性將整個文件下載下來的,那么 Content-Length 就表示這個文件的總大小。 > * 如果這條鏈接指定了 Range,表明了只是下載文件的指定部分的內容,那么此時 Content-Length 表示的就只是這一部分的大小。 所以,如果客戶端實現了下載進度實時更新功能時,需要注意一下。因為如果文件是斷點續傳的,那么進度條的分母就不能用每次 HTTP 鏈接中的 Content-Length。要么下載前先發一條獲取用于文件總大小的請求,然后一直維護著這個數據,要么就使用 Content-Range 字段。 ***** #### **Content-Range** Content-Range 字段也是出現在響應頭中,用于告知客戶端此鏈接下載的文件是哪個部分的,以及文件的總大小。 比如,當客戶端在請求頭中指定了`Range:bayes=501-1000`來下載一個總大小為 2000 字節文件的中間一部分內容時,此時,響應頭中的 Content-Range 字段信息如下: `Content-Range:bytes 501-1000/2000` 斜杠前表示此鏈接下載的文件是哪一部分,斜杠后表示文件的總大小。 ***** #### **If-Range** 斷點續傳,說白點也就是分多次下載,既然不是一次性下載,那么就無法保證多次下載的間隔。 也就是說,有可能出現這種場景: >這次由于某些原因只下載的一部分,而下次重啟繼續下載,但可能等到過了很多天后才重啟去繼續下載,如果在這期間,服務端的這份文件更新了怎么辦? 只要不是一次性下載的,那么就有可能會出現這種場景,顯然,這時候,就不希望斷點續傳了,而是要讓客戶端直接**重頭開始下載**,畢竟文件都已經發生更新了,不是同一份了,再繼續恢復下載也沒有什么意義。 **客戶端要如何知道服務端的文件是否發生變化,要重頭下載呢?** 這時就可以結合 If-Range 字段來實現了,這個也是在請求頭中的字段,跟 Range 字段一起使用,它的作用是給 Range 字段生效設置了一些條件,只有滿足這些條件,Range 才能生效。 也就是說,只有先滿足 If-Range,那么才能通過 Range 來實現斷點續傳。 那它的條件值可以設置為哪些呢?有兩種,Last-Modified 或者 ETag,這兩個也都是響應頭中的字段。**但不能將兩者同時使用。** (if-Range)參考鏈接:[https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/If-Range](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/If-Range) ***** #### **抓包:** > 1\. https://www.taobao.com/sw.js > 2. https://www.baidu.com/img/bd\_logo1.png?where=super > 3.https://mat1.gtimg.com/pingjs/ext2020/qqindex2018/dist/img/qq\_logo\_2x.png 4.https://www.magicdatatech.com/filespath/files/20191104064048.png 鯊魚軟件的抓包示例: ![](https://img.kancloud.cn/1e/04/1e0410999563f7e8b28e30f4bca3b3e9_416x366.png) 首先先發起一個請求,設置了不攜帶 BODY 信息,這樣就可以在下載前先獲取到文件的總大小。 ![](https://img.kancloud.cn/0f/99/0f990ce339c674d17136aefaf79d950e_506x481.png) 這是下載中斷后,重啟想要繼續下載時發起的請求信息,請求頭中指定了 `Range:bytes=12341380-` 表示本地已經下載了這么多,需要從這里開始繼續往下下載。 響應頭中返回了這部分的內容,并在 Content-Length 和 Content-Range 字段中給出了相關信息。 ``` // 創建一個XMLHttpRequest對象 // IE6, IE5 // var xhr = new ActiveXObject("Microsoft.XMLHTTP"); // IE7+, Firefox, Chrome, Opera, Safari var xhr = new XMLHttpRequest() // 重置服務器端返回的類型 xhr.overrideMimeType('image/png') // 初始化一個請求 參數3:表示該請求應該以`異步模式`執行。 xhr.open('GET', '[https://imgcps.jd.com/ling/7641991/5bmz5p2\_55S16KeG5beo5YiS566X/5L2g5YC85b6X5YWl5omL/p-5bd8253082acdd181d02f9d8/e129873b/590x470.jpg](https://imgcps.jd.com/ling/7641991/5bmz5p2_55S16KeG5beo5YiS566X/5L2g5YC85b6X5YWl5omL/p-5bd8253082acdd181d02f9d8/e129873b/590x470.jpg)', true) // 超時時間,單位是毫秒 xhr.timeout = 2000; // 設置 HTTP 請求頭的值。在`open()`之后、`send()`之前調用`setRequestHeader()`方法。 xhr.setRequestHeader('range', 'bytes=0-10') // 發送請求。如果請求是異步的(默認),那么該方法將在請求發送后立即返回。 xhr.send() // 只要 `readyState` 屬性發生變化,就會調用相應的處理函數。這個回調函數會被用戶線程所調用。當一個`XMLHttpRequest`請求被abort()方法取消時,其對應的 `readystatechange`事件不會被觸發。 xhr.onreadystatechange = function(){ if ( xhr.readyState == 4 && xhr.status == 206 ) { console.info(xhr) console.info( xhr.response); } else { console.info( xhr.statusText ); } } ``` ### **js 中的 Blob對象** https://www.jianshu.com/p/b322c2d5d778
                  <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>

                              哎呀哎呀视频在线观看