首页 > 其他分享 >大文件分片上传,断点续传整理

大文件分片上传,断点续传整理

时间:2023-09-26 18:36:34浏览次数:34  
标签:断点续传 key url token file 分片 uptoken 上传

问题:

前段时间做视频上传业务,通过网页上传视频到服务器。 视频大小 小则几十M,大则 1G+,以一般的HTTP请求发送数据的方式的话,会遇到的问题:
1、文件过大,超出服务端的请求大小限制;
2、请求时间过长,请求超时;
3、传输中断,必须重新上传导致前功尽弃;

探索过程:

1、原先咨询过组里的大佬给我推荐了百度的webupload,但后来引入之后发现它是基于jquery封装的。由于本身项目是基于vue开发的所以与jquery相关的开源框架就尽量不考虑了。
2、后来查阅了资料后自己手动实现了文件切片上传到服务器基本需求已经实现,但由于效率及稳定性问题后来决定还是直传文件到七牛云。一开始我使用了表单上传的方式实现了,后来种种原因又要求我做成分片上传。
3、引入七牛的jssdk。

解决方案:

1、修改服务端上传的限制配置;Nginx 以及 PHP 的上传文件限制 不宜过大,一般5M 左右为好;
2、大文件分片,一片一片的传到服务端,再由服务端合并。这么做的好处在于一旦上传失败只是损失一个分片而已,不用整个文件重传,而且每个分片的大小可以控制在4MB以内,服务端限制在4M即可。
3、使用七牛JavaScript SDK分片上传
首先,刚接触一门新的技术我们还是先去官方文档走一圈了解下基本用法~ 文档地址:JavaScript SDK

Qiniu-JavaScript-SDK 为客户端 SDK,没有包含 token 生成实现,为了安全,token 建议通过网络从服务端获取,具体生成代码可以参考服务端 SDK 的文档。

功能简介

  • 上传
    • 大于 4M 时可分块上传,小于 4M 时直传
    • 分块上传时,支持断点续传
  • 数据处理(图片)
    • imageView2(缩略图)
    • imageMogr2(高级处理,包含缩放、裁剪、旋转等)
    • imageInfo (获取基本信息)
    • exif (获取图片 EXIF 信息)
    • watermark (文字、图片水印)
    • pipeline (管道,可对 imageView2、imageMogr2、watermark 进行链式处理)

 后端返回给你的获取token的json格式必须是这种格式的。必须是一个json对象内部包裹着uptoken字段,带上其他字段也是可以的但是必须第一层要能找到uptoken

{

   "uptoken""0MLvWPnyya1WtPnXFy9KLyGHyFPNdZceomL...",    "xxx""..."    }

因为在它的sdk源码中是这么获取token的。他会先找定义的option字段中是否有uptoken,如果没有再去找uptoken_url有就发送ajax请求去获取uptoken字段,倘若后端必须要以他的格式为主那你可以修改sdk源码来实现。如果uptoken_url也没有值就回去调用uptoken_func函数都没有则报错,所以这三个必须指定一个。

// getUptoken maybe called at Init Event or BeforeUpload Event

       // case Init Event, the file param of getUptken will be set a null value        // if op.uptoken has value, set uptoken with op.uptoken        // else if op.uptoken_url has value, set uptoken from op.uptoken_url        // else if op.uptoken_func has value, set uptoken by result of op.uptoken_func        var getUpToken = function(file) {            if (op.uptoken) {                that.token = op.uptoken;                return;            else if (op.uptoken_url) {                logger.debug("get uptoken from: ", that.uptoken_url);                // TODO: use mOxie                var ajax = that.createAjax();                ajax.open('GET', that.uptoken_url, false);                ajax.setRequestHeader("If-Modified-Since""0");                // ajax.onreadystatechange = function() {                //     if (ajax.readyState === 4 && ajax.status === 200) {                //         var res = that.parseJSON(ajax.responseText);                //         that.token = res.uptoken;                //     }                // };                ajax.send();                if (ajax.status === 200) {                    var res = that.parseJSON(ajax.responseText);                    that.token = res.uptoken;                    logger.debug("get new uptoken: ", res.uptoken);                else {                    logger.error("get uptoken error: ", ajax.responseText);                }                return;            else if (op.uptoken_func) {                logger.debug("get uptoken from uptoken_func");                that.token = op.uptoken_func(file);                logger.debug("get new uptoken: ", that.token);                return;            else {                logger.error("one of [uptoken, uptoken_url, uptoken_func] settings in options is required!");            }        };

通过npm安装

npm install qiniu-js

在项目中使用import引入

import 'qiniu-js/dist/qiniu.min.js';

HTML

<div id="container">

    <div id="pickfiles">上传按钮</div> </div>

JavaScript

var uploader = Qiniu.uploader({

     runtimes: 'html5,flash,html4',      // 上传模式,依次退化(照着官网来就是了)      browse_button: 'pickfiles',         // 上传选择的点选按钮,必需(记得定义id并且保持一致)      // 在初始化时,uptoken,uptoken_url,uptoken_func三个参数中必须有一个被设置      // 切如果提供了多个,其优先级为uptoken > uptoken_url > uptoken_func      // 其中uptoken是直接提供上传凭证,uptoken_url是提供了获取上传凭证的地址,如果需要定制获取uptoken的过程则可以设置uptoken_func      uptoken : '<Your upload token>'// uptoken是上传凭证,由其他程序生成      uptoken_url: '/uptoken',         // Ajax请求uptoken的Url,强烈建议设置(服务端提供)      uptoken_func: function(){        // 在需要获取uptoken时,该方法会被调用         // do something(一般是发送手动发送ajax获取到token,如果后端返回格式不跟官方一致又不想该懂源代码可以通过这个方式调整)         return uptoken;      },      get_new_uptoken: false,             // 设置上传文件的时候是否每次都重新获取新的uptoken(没有特殊需求一般为false)      // downtoken_url: '/downtoken',(未使用到,可以不设置)      // Ajax请求downToken的Url,私有空间时使用,JS-SDK将向该地址POST文件的key和domain,服务端返回的JSON必须包含url字段,url值为该文件的下载地址      // unique_names: true,              // 默认false,key为文件名。若开启该选项,JS-SDK会为每个文件自动生成key(文件名)      // save_key: true,                  // 默认false。若在服务端生成uptoken的上传策略中指定了sava_key,则开启,SDK在前端将不对key进行任何处理      domain: '<Your bucket domain>',     // bucket域名,下载资源时用到,必需(找后端拿)      container: 'container',             // 上传区域DOM ID,默认是browser_button的父元素(如果不实现拖拽上传可以不设置)      max_file_size: '100mb',             // 最大文件体积限制(可以调大)      flash_swf_url: 'path/of/plupload/Moxie.swf',  //引入flash,相对路径(如果没用到flash上传的话可以不设置,一般支持html5上传的浏览器都不会用到它)      max_retries: 3,                     // 上传失败最大重试次数(自动帮你续传分片)      dragdrop: true,                     // 开启可拖曳上传(如果不实现拖拽上传可以不设置)      drop_element: 'container',          // 拖曳上传区域元素的ID,拖曳文件或文件夹后可触发上传(如果不实现拖拽上传可以不设置)      chunk_size: '4mb',                  // 分块上传时,每块的体积      auto_start: true,                   // 选择文件后自动上传,若关闭需要自己绑定事件触发上传      //x_vars : {                        // (未使用到,可以不设置)      //    查看自定义变量      //    'time' : function(up,file) {      //        var time = (new Date()).getTime();                // do something with 'time'      //        return time;      //    },      //    'size' : function(up,file) {      //        var size = file.size;                // do something with 'size'      //        return size;      //    }      //},      init: {          'FilesAdded'function(up, files) {              plupload.each(files, function(file) {                  // 文件添加进队列后,处理相关的事情              });          },          'BeforeUpload'function(up, file) {                 // 每个文件上传前,处理相关的事情                 // (上传文件前做一些处理)          },          'UploadProgress'function(up, file) {                 // 每个文件上传时,处理相关的事情                 // (可以设置进度条信息)          },          'FileUploaded'function(up, file, info) {                 // 每个文件上传成功后,处理相关的事情                 // 其中info是文件上传成功后,服务端返回的json,形式如:                 // {                 //    "hash": "Fh8xVqod2MQ1mocfI4S4KpRL6D98",                 //    "key": "gogopher.jpg"                 //  }                 // 查看简单反馈                 // var domain = up.getOption('domain');                 // var res = parseJSON(info);                 // var sourceLink = domain +"/"+ res.key; 获取上传成功后的文件的Url          },          'Error'function(up, err, errTip) {                 //上传出错时,处理相关的事情          },          'UploadComplete'function() {                 //队列文件处理完毕后,处理相关的事情          },          'Key'function(up, file) {              // 若想在前端对每个文件的key进行个性化处理,可以配置该函数              // 该配置必须要在unique_names: false,save_key: false时才生效                var key = "";              // do something with key here              // (可以自定义key不设定默认是文件名)              return key          }      }  });    // domain为七牛空间对应的域名,选择某个空间后,可通过 空间设置->基本设置->域名设置 查看获取    // uploader为一个plupload对象,继承了所有plupload的方法

总结

由于本次项目中只涉及到大文件上传,没有图像处理等相关的api使用经验官方的案例就不多讲了。总结起来七牛云上传的套路就是后台为你提供uptoken或者获取uptoken的接口地址之后上传的时候要带上这个token。返回的字段最好是按照官方的格式来,如果不是的话也可以修改源代码或者在uptoken_func中手动获取,另外如果要修改上传的服务器也是要在qiniu.js中修改

/**

    * qiniu upload urls     * 'qiniuUploadUrls' is used to change target when current url is not avaliable     * @type {Array}     */    var qiniuUploadUrls = [        // "http://upload.qiniu.com",        // "http://up.qiniu.com",        "修改成你需要的地址",    ];

如果使用表单上传的话可以不引用任何插件,代码实现如下:

<form id="testform" method="post" enctype="multipart/form-data">

            <input name="key" id="key" type="hidden" value="">             <input name="token" type="hidden" id="token" value="">             <input id="userfile" name="file" type="file" />               <!-- take photo with phone -->             <!-- <input id="userfile" name="file" accept="image/*" type="file" /> -->               <!-- take video with phone -->             <!-- <input id="userfile" name="file" type="file" accept="video/*"/> -->               <input name="accept" type="hidden" />         </form>   js:     upload() {         const formdata = new FormData(document.getElementById('testform'));         $.ajax({             url: '上传的七牛云服务器,后端提供'// 'http://up.qiniu.com'             method: 'post',             success: function(data) {                 console.log(data);             },         })         ...     }

需要注意的是,每个input都需要定义好那么属性,并且token不能为空,需要提前通过ajax去后端获取或者使用后端给定的token否则上传会失败~

 

参考文章:http://blog.ncmem.com/wordpress/2023/09/26/%e5%a4%a7%e6%96%87%e4%bb%b6%e5%88%86%e7%89%87%e4%b8%8a%e4%bc%a0%ef%bc%8c%e6%96%ad%e7%82%b9%e7%bb%ad%e4%bc%a0%e6%95%b4%e7%90%86/

欢迎入群一起讨论

 

 

 

 

 

标签:断点续传,key,url,token,file,分片,uptoken,上传
From: https://www.cnblogs.com/songsu/p/17730886.html

相关文章

  • 实现一个大文件上传和断点续传
    本文将从零搭建前端和服务端,实现一个大文件上传和断点续传的demo前言本文将从零搭建前端和服务端,实现一个大文件上传和断点续传的demo前端:vueelement-ui服务端:nodejs文章有误解的地方,欢迎指出,将在第一时间改正,有更好的实现方式希望留下你的评论大文件上传整体思路前端......
  • springboot大文件上传、分片上传、断点续传、秒传的实现
    对于大文件的处理,无论是用户端还是服务端,如果一次性进行读取发送、接收都是不可取,很容易导致内存问题。所以对于大文件上传,采用切块分段上传,从上传的效率来看,利用多线程并发上传能够达到最大效率。 本文是基于springboot+vue实现的文件上传,本文主要介绍服务端实现文件上传的......
  • 浅析实现大文件上传和断点续传
    大文件上传:前端部分:核心是利用 Blob.prototype.slice 方法,和数组的slice方法相似,调用的slice方法可以返回原文件的某个切片。根据预先设置好的切片最大数量将文件切分为一个个切片,然后借助http的可并发性,同时上传多个切片。这样从原本传一个大文件,变成了同时传多个小......
  • 大文件上传如何做断点续传
    断点续传是什么?断点续传(ResumableFileUpload)是一种文件上传的技术,它允许在上传过程中出现中断或失败的情况下,能够从中断的位置继续上传,而不需要重新上传整个文件。这在处理大文件或不稳定的网络连接时非常有用。断点续传的实现通常涉及以下几个关键概念和步骤:分片:将大文件分......
  • file文件上传后 添加水印 并且生成file文件 使用formData上传
    functionhecheng(){//创建一个canvasconstd2=testCanvas.getContext('2d');//准备图片1consturl=URL.createObjectURL(file.files[0]);varimg=docu......
  • windows系统上的github项目的上传和下载
    通过把远程仓库文件克隆下来,再添加自己需要上传的文件,再上传到远程仓库。 1、下载git工具:https://gitforwindows.org/下载安装之后,右键鼠标会出现两个新选项,分别为[GitGUIHere],[GitBashHere] 2、进入GitHub首页,点击Newrepository新建一个项目仓库Re......
  • vue实现大文件切片上传、断点续传、并发数控制等
     一、上传按钮和进度条等<div><h2>上传文件</h2><divref="drag"class="drag"><inputclass="file"type="file"@change="handlerChange"/></div><el-progressstyle="......
  • 文件上传 切片与断点续传
    主要讲前端,后端使用node。会写一下后端的处理1.单个文件上传请求头为multipart/form-data数据为from-data格式letformData=newFormData();formData.append('file',_file);formData.append('filename',_file.name);然后使用post直接给后端。后端直接存......
  • Tomcat--文件上传--文件包含--(CVE-2017-12615)&&(CVE-2020-1938)
    Tomcat--文件上传--文件包含--(CVE-2017-12615)&&(CVE-2020-1938)复现环境采用Vulfocus靶场环境进行复现,搭建操作和文章参考具体搭建教程参考vulfocus不能同步的解决方法/vulfocus同步失败。CVE-2017-12615文件上传漏洞简介当存在漏洞的Tomcat运行在Windows/Linux主机上,且......
  • 大文件切片上传+断点续传解决方案-前后端实现
    上传文件大家应该都做过,前端直接把file文件传给后端就ok了,但是大文件这样传就会造成页面假死,体验极差。如果遇到网络不稳定的时候,中途上传失败的话,又要从头开始传,本来文件就大,还慢。所以今天我们用一种新方法-切片上传+断点续传前端实现:页面上很简单,我就放了进度条和一个上传文件......