使用Node.js实现HTTP 206内容分片的教程

2020-06-17 06:47:38易采站长站整理

* Output: [null, 100, 200, null] *
* Input: bytes=-200
* Output: [null, null, 200, null] */

if (range == null || range.length == 0)
return null;

var array = range.split(/bytes=([0-9]*)-([0-9]*)/);
var start = parseInt(array[1]);
var end = parseInt(array[2]);
var result = {
Start: isNaN(start) ? 0 : start,
End: isNaN(end) ? (totalLength - 1) : end
};

if (!isNaN(start) && isNaN(end)) {
result.Start = start;
result.End = totalLength - 1;
}

if (isNaN(start) && !isNaN(end)) {
result.Start = totalLength - end;
result.End = totalLength - 1;
}

return result;
}

步骤 3 – 检查数据范围是否合理

回到函数 httpListener(), 在HTTP方法通过之后,现在我们来检查请求的数据范围是否可用. 如果浏览器没有发送 Range 消息头过来, 请求就会直接被当做一般的请求对待. 服务器会返回整个文件,HTTP状态将会是 200 OK. 另外我们还会看看开始和结束位置是否比文件长度更大或者相等. 只要有一个是这种情况,请求的数据范围就是不能被满足的. 返回的状态就将会是 416 Requested Range Not Satisfiable 而 Content-Range 也会被发送. 
 


var responseHeaders = {};
var stat = fs.statSync(filename);
var rangeRequest = readRangeHeader(request.headers['range'], stat.size);

// If 'Range' header exists, we will parse it with Regular Expression.
if (rangeRequest == null) {
responseHeaders['Content-Type'] = getMimeNameFromExt(path.extname(filename));
responseHeaders['Content-Length'] = stat.size; // File size.
responseHeaders['Accept-Ranges'] = 'bytes';

// If not, will return file directly.
sendResponse(response, 200, responseHeaders, fs.createReadStream(filename));
return null;
}

var start = rangeRequest.Start;
var end = rangeRequest.End;

// If the range can't be fulfilled.
if (start >= stat.size || end >= stat.size) {
// Indicate the acceptable range.
responseHeaders['Content-Range'] = 'bytes */' + stat.size; // File size.

// Return the 416 'Requested Range Not Satisfiable'.
sendResponse(response, 416, responseHeaders, null);
return null;
}

步骤 4 – 满足请求

最后使人迷惑的一块来了。对于状态 216 Partial Content, 我们有另外一种格式的 Content-Range 消息头,包括开始,结束位置以及当前文件的总字节数. 我们也还有 Content-Length 消息头,其值就等于开始和结束位置之间的差。在最后一句代码中,我们调用了 createReadStream() 并将开始和结束位置的值给了第二个参数选项的对象, 这意味着返回的流将只包含从开始到结束位置的只读数据.