http 206斷點續傳與文件下載原理解析

jopen 8年前發布 | 64K 次閱讀 PHP開發

 一、斷點續傳的原理

       其實斷點續傳的原理很簡單,就是在http的請求上和一般的下載有所不同而已。

       打個比方,瀏覽器請求服務器上的一個文時,所發出的請求如下:

       假設服務器域名為www.jizhuomi.com/android,文件名為down.zip。

get /down.zip http/1.1
accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-
excel, application/msword, application/vnd.ms-powerpoint, */*
accept-language: zh-cn
accept-encoding: gzip, deflate
user-agent: mozilla/4.0 (compatible; msie 5.01; windows nt 5.0)
connection: keep-alive

    服務器收到請求后,按要求尋找請求的文件,提取文件的信息,然后返回給瀏覽器,返回信息如下:

content-length=106786028
accept-ranges=bytes
date=mon, 30 apr 2001 12:56:11 gmt
etag=w/"02ca57e173c11:95b"
content-type=application/octet-stream
server=microsoft-iis/5.0
last-modified=mon, 30 apr 2001 12:56:11 gmt


     所謂斷點續傳,也就是要從文件已經下載的地方開始繼續下載。所以在客戶端瀏覽器傳給web服務器的時候要多加一條信息--從哪里開始。

      下面是用自己編的一個“瀏覽器”來傳遞請求信息給web服務器,要求從2000070字節開始。

get /down.zip http/1.0
user-agent: netfox
range: bytes=2000070-
accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2

  仔細看一下就會發現多了一行 range: bytes=2000070-

       這一行的意思就是告訴服務器down.zip這個文件從2000070字節開始傳,前面的字節不用傳了。

       服務器收到這個請求以后,返回的信息如下:

206
content-length=106786028
content-range=bytes 2000070-106786027/106786028
date=mon, 30 apr 2001 12:55:20 gmt
etag=w/"02ca57e173c11:95b"
content-type=application/octet-stream
server=microsoft-iis/5.0
last-modified=mon, 30 apr 2001 12:55:20 gmt


 和前面服務器返回的信息比較一下,就會發現增加了一行:

content-range=bytes 2000070-106786027/106786028

返回的代碼也改為206了,而不再是200了。

 知道了以上原理,就可以進行斷點續傳的編程了。

二.文件下載和在瀏覽器顯示

文件下載原理主要控制來自于服務器端響應,瀏覽器或者httpClient自行讀取IO流

Accept-Ranges:bytes  #接受類型
Access-Control-Allow-Origin:* #允許任何主機均可跨域訪問,ajax同樣可以
Access-Control-Max-Age:2592000
Cache-Control:public, max-age=31536000
Connection:keep-alive
Content-Disposition:attachment; filename="c501b_01_h264_sd_960_540.mp4"
Content-Length:14470485
Content-Transfer-Encoding:binary #傳輸類型,字節類型
Content-Type:video/mp4  #響應類型
Date:Sun, 25 Jan 2015 00:17:14 GM  #文件日期--注意,對于瀏覽器讀取緩存而不重新請求服務器十分有用,用來檢測靜態文件有沒有被修改
ETag:"lraEcGPNv-73F2tLNOKhuA8a6pFa" #

下面是一個簡單的好PHP下載實例

<?php
$file_name="哈哈.jpg";//需要下載的文件
$file_name=iconv("utf-8","gb2312","$file_name");
$fp=fopen($file_name,"r+");//下載文件必須先要將文件打開,寫入內存
if(!file_exists($file_name)){//判斷文件是否存在
    echo "文件不存在";
    exit();
}
$file_size=filesize("a.jpg");//判斷文件大小
//返回的文件
Header("Content-type: application/octet-stream");
//按照字節格式返回
Header("Accept-Ranges: bytes");
//返回文件大小
Header("Accept-Length: ".$file_size);
//彈出客戶端對話框,對應的文件名
Header("Content-Disposition: attachment; filename=".$file_name);
//防止服務器瞬時壓力增大,分段讀取
$buffer=1024;
while(!feof($fp)){
    $file_data=fread($fp,$buffer);
    echo $file_data;
}
//關閉文件
fclose($fp);
?>


三.關于在瀏覽器中顯示文件內容

瀏覽器默認會顯示一些 text/*,image/*,PDF類型的文件,但默認會變成自動下載,這是我們需要修改響應頭為

Content-Disposition:inline; filename="c501b_01_h264_sd_960_540.mp4"


來自: http://my.oschina.net/ososchina/blog/371468

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!