使用字节范围请求服务器时如何处理浏览器中的二进制数据

How to handle binary data in the browser when using byte range requests to server

我正在试验受控文件请求。浏览器将使用字节范围请求从服务器获取大文件。这可能是视频文件或某种大型数据文件。我已经能够使用 request 模块设置一个简单的获取来获取一系列数据。

request({
    url: 'http://localhost:8080' + file.path, 
    headers: {
        'Range' : 'bytes=0-50'
    }
}, function (err, res, body) {
    console.log('err: ', err);
    console.log('status: ', res.statusCode);
    console.log('body: ', body);
});

这会产生以下输出:

err:  null
status:  206
body:  ftypisomisomavc1.��moovlmvhdК{�К{

所以,我正在获取数据,但是我不确定处理此二进制数据并保持其完整性的最佳方法。具体来说:

  1. 将其作为二进制数据加载,这样我就可以继续拼凑块并最终向用户提供可下载的文件。

  2. 对传入数据执行某种类型的校验和或完整性检查(假设我可以获得每个块的 md5,可能作为预取列表)。

原来问题是因为我使用的是 request 模块,它不与本机浏览器 XMLHttpRequest API 接口,因此无法请求二进制数据。我做了一个简单的小 request 函数,它包装了 XMLHttpRequest API 并返回二进制数据 (blob).

function request (url, _opt, cb) {
    var xhr = new XMLHttpRequest();
    var opt = {
        method: 'GET'
    };
    if (typeof _opt === 'function') {
        cb = _opt;
    } else {
        opt = _opt;
    }
    opt.method = (opt.method) ? opt.method : 'GET';
    xhr.open(opt.method, url, true);
    xhr.responseType = 'blob';

    if (typeof opt.headers === 'object') {
        var keys = Object.keys(opt.headers);
        for (var i = 0, len = keys.length; i < len; i += 1) {
            xhr.setRequestHeader(keys[i], opt.headers[keys[i]]);
        }
    }

    xhr.onload = function (e) {
        if ((this.status >= 200) && (this.status < 299)) {
            // get binary data as a response
            cb(null, this, this.response);
        } else {
            cb('received error code: ' + this.status, this);
        }
    };

    xhr.send();
}

并且可以像这样使用它:

request(file.path, {
    headers: {
        'Range' : file.range
    }
}, function (err, res, body) {
    if (err) { throw new Error(err) ; }
    var contentType = res.getResponseHeader ("Content-Type");
    cb(contentType, body);
});