HTTP range requests
HTTP范围请求仅允许将HTTP消息的一部分从服务器发送到客户端。例如,部分请求对于大型媒体或具有暂停和恢复功能的文件下载很有用。
https://developer.mozilla.org/en-US/docs/Web/HTTP/Range_requests
检查服务器是否支持范围请求
假如在响应中存在 Accept-Ranges 首部(并且它的值不为 “none”),那么表示该服务器支持范围请求。
其实标准的服务器会发送206
响应,并且标头还有:
'accept-ranges': 'bytes',
'content-range': 'bytes 0-2036635788/2036635789',
通常发送一个HEAD请求来检测。
import * as http from 'http';
import * as https from 'https';
import { URL } from 'url';
/**
* 判断url是否支持范围请求
* @param url
*/
function isSupportedRange(url: URL | string): Promise<boolean> {
return new Promise((resolve, reject) => {
if (typeof url === 'string') url = new URL(url);
const options: http.RequestOptions = {
method: 'HEAD',
headers: {
'Range': 'bytes=0-',
},
};
let req: http.ClientRequest; // 根据URL协议,判断使用http还是https模块发送请求
function callback(response: http.IncomingMessage) {
// console.log(response.statusCode);
// console.log(response.headers);
// 假如在响应中存在 Accept-Ranges 首部(并且它的值不为 “none”),那么表示该服务器支持范围请求。
if (response.statusCode === 206 || (response.headers["accept-ranges"] && response.headers["accept-ranges"] !== 'none')) resolve(true);
resolve(false);
}
switch (url.protocol) {
case 'http:': {
req = http.request(url, options, callback);
break;
}
case 'https:': {
req = https.request(url, options, callback);
break;
}
default: return void resolve(false);
}
req.addListener('error', (err: Error) => {
reject(err); // 请求失败
});
req.end(); // refresh request stream
});
}
断点续传原理
静态Web服务器支持仅发送静态资源的指定范围数据, 请求头为 Range
$ telnet abc.com 80
HEAD /rap.flv HTTP/1.1
Host: a.c
RANGE: bytes=2000070-
HTTP/1.1 206 Partial Content
Server: nginx
Date: Sun, 02 Jun 2019 14:10:43 GMT
Content-Type: video/x-flv
Content-Length: 16404710
Last-Modified: Fri, 26 Apr 2019 07:18:55 GMT
Connection: keep-alive
ETag: "5cc2b0df-118d5ac"
developer: develon
原始uri: /rap.flv
Content-Range: bytes 2000070-18404779/18404780
HEAD /rap.flv HTTP/1.1
Host: a.c
RANGE: bytes=2000070-2000071
HTTP/1.1 206 Partial Content
Server: nginx
Date: Sun, 02 Jun 2019 14:11:43 GMT
Content-Type: video/x-flv
Content-Length: 2
Last-Modified: Fri, 26 Apr 2019 07:18:55 GMT
Connection: keep-alive
ETag: "5cc2b0df-118d5ac"
developer: develon
原始uri: /rap.flv
Content-Range: bytes 2000070-2000071/18404780
URL url = new URL("http://www.sjtu.edu.cn/down.zip");
HttpURLConnection httpConnection = (HttpURLConnection)url.openConnection();
// 设置 User-Agent
httpConnection.setRequestProperty("User-Agent","NetFox");
// 设置断点续传的开始位置
httpConnection.setRequestProperty("RANGE","bytes=2000070");
// 获得输入流
InputStream input = httpConnection.getInputStream();
https://www.ibm.com/developerworks/cn/java/joy-down/index.html