纯js下载媒体文件至本地(分片下载)

ZhuMeng-Chao / 2023-08-24 / 原文

效果

 

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">&#xe619;</i>下载</button>
            <button type="button" class="layui-btn layui-btn-primary" data-pwid="usclose"><i class="us-icon">&#xe638;</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:进度条)