纯js下载媒体文件至本地(分片下载)
效果
html:
<div class="usnbox"> <div class="usnboxbody usnboxbody_rtm"> <div class="layui-form-item"> <div class="layui-inline"> <label class="layui-form-label">时长</label> <div class="layui-input-inline"> <input type="text" name="timelength" value="" autocomplete="off" placeholder="时长" class="layui-input noedit" disabled> </div> <label class="layui-form-label">文件大小</label> <div class="layui-input-inline"> <input type="text" name="filesize" value="" autocomplete="off" placeholder="文件大小" class="layui-input noedit" disabled> </div> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">文件名称<span class="usStar"></span></label> <div class="layui-input-block"> <input type="text" name="filename" lay-verify="required" autocomplete="off" placeholder="文件名称" class="layui-input noedit" disabled> </div> </div> <div class="layui-form-item"> <label class="layui-form-label"> 文件地址<span class="usStar"></span> </label> <div class="layui-input-block"> <input type="text" name="vurl" lay-verify="required" autocomplete="off" placeholder="文件路径" class="layui-input noedit" disabled> </div> </div> <div class="layui-form-item"> <div class="layui-progress layui-progress-big" style="width:100%;margin-top:20px;" lay-showPercent="true" lay-filter="updprogress"> <div class="layui-progress-bar" lay-percent="0%"></div> </div> </div> </div> </div> <div class="layui-form-item us-submitsave"> <div class="uscenter"> <button class="layui-btn" onclick="upload()"><i class="us-icon"></i>下载</button> <button type="button" class="layui-btn layui-btn-primary" data-pwid="usclose"><i class="us-icon"></i>关闭</button> </div> </div>
js方法实现下载:
<script> var element; $(function () { //layui操作句柄 layui.use('element', function () { element = layui.element; }) }) async function upload() { //获取文件路径 var vurl = $("input[name=vurl]").val(); //获取文件名称 var filename = $("input[name=filename]").val(); const CHUNK_SIZE = 1024 * 1024 * 10; // 每次下载10MB const response = await fetch(vurl); //不添加avait控制台会报错,下面也获取不到文件大小 const contentRange = response.headers.get('content-range'); //获取下载文件大小 const fileSize = contentRange ? Number(contentRange.split('/')[1]) : response.headers.get('content-length'); const fileStream = []; let offset = 0; //进行分片 while (offset < fileSize) { const end = Math.min(offset + CHUNK_SIZE, fileSize); const options = { headers: { 'Range': `bytes=${offset}-${end - 1}` } };
//不加await,文件大也会下载很快,但是下载后的文件打开无效,必须加await const blob = await fetch(vurl, options).then(res => res.blob()) fileStream.push(blob); offset = end; //console.error(offset); //console.error(fileSize); var p = Math.floor(offset / fileSize * 100); //设置layui进度条 setprogress(p); }; //结束后,组装分片 const blob = new Blob(fileStream, { type: response.headers.get('content-type') }); //保存,触发浏览器的下载窗口 saveAs(blob, filename); } //保存 function saveAs(blob, filename) { const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = filename; a.click(); } //设置layui进度条(动态) function setprogress(p) { p = p + '%'; console.error(p); element.progress('updprogress', p); } </script>
第二种:试用于小文件(不需要分片)
js 实现浏览器下载视频2种方法
<script> function updloadvideo() { var vurl="文件路径“ var xhr = new XMLHttpRequest(); xhr.open('get', vurl, true); // 也可以使用POST方式,根据接口 xhr.responseType = "blob"; // 返回类型blob xhr.onload = function () { //console.error(this.status); if (this.status === 200) { console.error("200"); var blob = this.response; var reader = new FileReader(); reader.readAsDataURL(blob); // 转换为base64,可以直接放入a表情href reader.onload = function (e) { var a = document.createElement('a'); a.download = fileName; //下载文件名 a.href = e.target.result; a.click(); window.URL.revokeObjectURL(e.target.result) }; } }; xhr.send(); } </script>
参考文献:
javascript 大文件下载,分片下载,断点续传
layui框架学习(12:进度条)