이 기사의 내용은 http Range Requests 프로토콜을 기반으로 분할 다운로드를 구현하는 기능에 대한 내용입니다. 필요한 친구들이 참고할 수 있기를 바랍니다.
이 글은 http Range Requests 프로토콜을 기반으로 하며 분할된 다운로드 기능을 구현합니다.
사용 시나리오에는 브라우저 기반 스트리밍 파일 조각 전송, 클라이언트 기반 분할 다운로드 등이 포함됩니다.
http는 Range Requests 관련 헤더를 통해 서버와 협상하여 부분 요청을 구현할 수 있습니다.
구현 과정은 아래에 게시되어 있습니다: https://github.com/keller35/partial.
서버는 노드를 사용하여 구현됩니다.
const fs = require('fs'); const path = require('path'); const Koa = require('koa'); const app = new Koa(); const PATH = './resource'; app.use(async ctx => { const file = path.join(__dirname, `${PATH}${ctx.path}`); // 1、404检查 try { fs.accessSync(file); } catch (e) { return ctx.response.status = 404; } const method = ctx.request.method; const { size } = fs.statSync(file); // 2、响应head请求,返回文件大小 if ('HEAD' == method) { return ctx.set('Content-Length', size); } const range = ctx.headers['range']; // 3、通知浏览器可以进行分部分请求 if (!range) { return ctx.set('Accept-Ranges', 'bytes'); } const { start, end } = getRange(range); // 4、检查请求范围 if (start >= size || end >= size) { ctx.response.status = 416; return ctx.set('Content-Range', `bytes */${size}`); } // 5、206分部分响应 ctx.response.status = 206; ctx.set('Accept-Ranges', 'bytes'); ctx.set('Content-Range', `bytes ${start}-${end ? end : size - 1}/${size}`); ctx.body = fs.createReadStream(file, { start, end }); }); app.listen(3000, () => console.log('partial content server start')); function getRange(range) { var match = /bytes=([0-9]*)-([0-9]*)/.exec(range); const requestRange = {}; if (match) { if (match[1]) requestRange.start = Number(match[1]); if (match[2]) requestRange.end = Number(match[2]); } return requestRange; }
코드로 구현된 기능적 논리는 대략 다음과 같습니다.
#🎜 🎜#요청에서 범위를 설정한 경우 해당 범위가 적합한지 확인하고, 적합하지 않은 경우 적합한 범위를 반환합니다.
Everything 정상입니다. 파일의 범위 부분을 가져와 스트림 응답을 만듭니다
<title>分片流传输</title> <script> function jump() { const player = document.getElementById('musicPlayer'); // 从30s开始播放 player.currentTime = 30; } </script> <audio></audio> <button>切到30s</button>
비교 두 그림, HTML이 로드되면 브라우저가 자동으로 리소스를 요청하고 헤더에
이 있습니다.이 서버 코드를 사용하여 유사하게 클라이언트를 구현하여 하도급 다운로드를 시뮬레이션할 수도 있습니다.
노드 하위 패키지 다운로드Range: bytes=0-
,表示从第0 byte开始加载资源;当点击跳到30s处播放时,此时header变成了Range: bytes=3145728-
import request from 'request'; import path from 'path'; import fs from 'fs'; const SINGLE = 1024 * 1000; const SOURCE = 'http://127.0.0.1:3000/source.mp3'; request({ method: 'HEAD', uri: SOURCE, }, (err, res) => { if (err) return console.error(err); const file = path.join(__dirname, './download/source.mp3'); try { fs.closeSync(fs.openSync(file, 'w')); } catch (err) { return console.error(err); } const size = Number(res.headers['content-length']); const length = parseInt(size / SINGLE); for (let i=0; i<length> { const range = resp.headers['content-range']; const match = /bytes ([0-9]*)-([0-9]*)/.exec(range); start = match[1]; end = match[2]; }).pipe(fs.createWriteStream(file, {start, end})); } });</length>
위 내용은 http Range Requests 프로토콜을 기반으로 분할된 다운로드 기능 구현의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!