前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >七牛 JSSDK 配置+常见问题

七牛 JSSDK 配置+常见问题

作者头像
jojo
发布2022-03-21 20:41:07
1K0
发布2022-03-21 20:41:07
举报
文章被收录于专栏:jojo的技术小屋jojo的技术小屋

作者:汪娇娇

时间:2017年7月7日

一、铺垫

依靠七牛上传图片,其实有很多方法,先说说有哪些方法,以及这些方法各自的优缺点吧。

way1:前端只负责选择图片,然后将图片传给服务端,服务端再传给七牛,再将地址返给前端展示。

优:可以控制上传图片到七牛的时机,不浪费七牛的存储空间;

缺:浪费自己服务器的带宽,并且周周转转,耗时长,麻烦。

way2:前端发通知让客户端来上传图片到七牛。

优:前端不需要处理太多东西,只需要给客户端发一个通知。

缺:选一张图片就上传了一张,如果多次选择,会浪费七牛存储空间。

way3:前端集成七牛的jssdk。

优:可以控制上传图片到七牛的时机,不浪费七牛的存储空间;不通过服务端,所以不会消耗服务器带宽;不通过客户端,所以不需要集成javascriptBridge和客户端通信。

缺:路漫漫其修远兮,需要自己去踩坑。。。。

二、七牛 JSSDK

下面正式进入七牛JSSDK:

1、把该引入的文件都引入了。

三个文件:

(1)产品环境:plupload、plupload.full.min.js、qiniu.min.js

(2)开发调试:plupload.dev.js 、moxie.js、qiniu.js

2、初始化uploader 。

代码语言:javascript
复制
 var uploader = Qiniu.uploader({
      runtimes: 'html5,flash,html4',      // 上传模式,依次退化
      browse_button: 'pickfiles',         // 上传选择的点选按钮,必需,id名
      uptoken : '<Your upload token>', // uptoken是上传凭证,由其他程序生成
      get_new_uptoken: false,             // 设置上传文件的时候是否每次都重新获取新的uptoken
      // 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,相对路径
      max_retries: 3,                     // 上传失败最大重试次数
      dragdrop: true,                     // 开启可拖曳上传
      drop_element: 'container',          // 拖曳上传区域元素的ID,拖曳文件或文件夹后可触发上传
      chunk_size: '4mb',                  // 分块上传时,每块的体积
      auto_start: true,                   // 选择文件后自动上传,若关闭需要自己绑定事件触发上传
      init: {
          'FilesAdded': function(up, files) {
              // 文件添加进队列后,处理相关的事情
          },
          '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 = JSON.parse(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 = "jojojo/" + file.id;  //可以加上自己设定好的前缀(归类好了,自己易管理)
              return key;
          }
      }
  });

三、常见问题

1、uptoken

uptoken由服务端提供。

uptoken(上传凭证)、uptoken_url(获取上传凭证的地址)、uptoken_func(获取uptoken的过程)三个参数只要有一个被设置就ok。

如果提供了多个,优先级:uptoken > uptoken_url > uptoken_func。

推荐使用uptoken,服务端可以设置一些权限,更安全;使用uptoken_url,相当于将这个接口直接暴露出去,存在安全隐患。

代码语言:javascript
复制
uptoken : '<Your upload token>', // uptoken是上传凭证,由其他程序生成
uptoken_url: '/uptoken',         // Ajax请求uptoken的Url,强烈建议设置(服务端提供),格式:{"uptoken":"<upload token>"}
uptoken_func: function(){        // 在需要获取uptoken时,该方法会被调用
      // do something
      return uptoken;
},

2、上传单张图片

将multi_selection设置为false就可以了。

代码语言:javascript
复制
multi_selection: false,

但有的webview并不支持这个属性,依旧可以选择多张图片,特殊情况特殊处理。

在FileAdded函数中处理:

代码语言:javascript
复制
'FilesAdded': function(up, files) {
      plupload.each(files, function(file) {
            // 针对multi_selection失效时的处理办法:无论选多少个,只留一个
            if(up.files.length > 1){
                   up.removeFile(up.files[0]);  //移除多余的文件
            }
      });
},

3、图片加入队列时就实现预览(不是上传完成后)

都知道上传完成后,会获取到图片的一个链接,这样很容易实现展示。但如果想在图片加入队列时就预览图片,稍稍麻烦点,但也不是没有办法。

在FileAdded函数中处理:

代码语言:javascript
复制
'FilesAdded': function(up, files) {
      plupload.each(files, function(file) {
            //针对加入队列时,而不是上传完成后才可以预览图片的处理办法
            var preloader = new mOxie.Image(); 
            preloader.onload = function() { 
                 $('body').append('<img src="'+preloader.getAsDataURL()+'">');
            };
            preloader.load( file.getSource() ); 
      });
},

4、 Android 自带的 Webview 对JS SDK不支持

Android里点击“选择文件”按钮没有反应,这是Webview 对 JS 不是很支持造成的,解决方法:要求Android客户端引入七牛的Webview ,jar包地址:

https://o8qpi53g2.qnssl.com/Android-AdvancedWebView.jar

使用方法请参考:

代码语言:javascript
复制
private AdvancedWebView mWebView;
@Override
protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_main);
     mWebView = (AdvancedWebView) findViewById(R.id.webview);
     mWebView.setListener(this, this);
     mWebView.loadUrl("http://jssdk.demo.qiniu.io/");
}

5、取消自动上传

将auto_start设置为false,绑定自定义的事件触发上传。

代码语言:javascript
复制
auto_start: false,
代码语言:javascript
复制
document.getElementById("btn").onclick = function(){
     uploader.start();
}

但这其中还是会存在问题的。

比如说,你上传文件后,要把上传后的链接和其他一些数据传给服务端,现在的逻辑应该是把上传给服务器的操作放在FileUploaded里面,这样才能保证拿到链接。

但如果你选定一张图片后,只是改变其他数据的变化,那你每次都要uploader.start()吗?但事实是,只要你选定一张图片后,uploader.start()只会生效一次,后来就不生效了,那放在uploader.start()里的操作就不执行了,这并不是我们想要的结果。

那就做个判断,如果再选择另外一张图片了,就执行uploader.start(),如果一直没再选择另外一张图片,就直接执行和服务端的交互。那问题是,怎么判断别人有没有选择另外一张图片呢?

用标记法。标记一个flag=0(初始状态),选择图片后,在FileAdded里设置flag=1,代表进入新的图片。上传完成后,也就是在fileUploaded里设置flag=0,代表图片上传完成,只要没有新图片加入,flag一直为0,就可以直接执行和服务端的交互。一旦新图片加入队列,flag=1,就可以执行uploader.start()了。

6、限制上传文件的类型

代码语言:javascript
复制
// 可以使用该参数来限制上传文件的类型,大小等,该参数以对象的形式传入,它包括三个属性:
filters : {
    max_file_size : '100mb',
    prevent_duplicates: true,   //是否可以上传重复的图片,true:不能重复,false:可以重复
    mime_types: [
        {title : "flv files", extensions : "flv"} // 限定flv后缀上传格式上传
        {title : "Video files", extensions : "flv,mpg,mpeg,avi,wmv,mov,asf,rm,rmvb,mkv,m4v,mp4"}, // 限定flv,mpg,mpeg,avi,wmv,mov,asf,rm,rmvb,mkv,m4v,mp4后缀格式上传
        {title : "Image files", extensions : "jpg,gif,png"}, // 限定jpg,gif,png后缀上传
        {title : "Zip files", extensions : "zip"} // 限定zip后缀上传
    ]
},

6、修改上传文件命名

将unique_names和save_key都设置为false,并在Key函数中做相关处理。

代码语言:javascript
复制
unique_names: false,
save_key: false, 
代码语言:javascript
复制
'Key': function(up, file) {
     var key = "jojojo/" + file.id;  //可以加上你的个性前缀(好归类,自己好管理)
     return key;
}

假设domain是:https://www.jojojojo.com

默认得到的文件名是:https://www.jojojojo.com/h53434d8h3jj0

修改之后的文件名是:https://www.jojojojo.com/jojojo/h53434d8h3jj0

修改之后的有了归类,更容易管理。

7、关于多个按钮选择文件的 Demo

很多用户都在问 JSSDK 多文件选择的 Demo,其实只需要在 main.js 文件里多 new 几个 Uploader 对象,然后在主页上写好对应的上传按钮就可以了。

main.js 里面多 new 几个 uploader 对象:

代码语言:javascript
复制
$(function() {
    var uploader = Qiniu.uploader({
        runtimes: 'html5,flash,html4',
        browse_button: 'pickfiles',
        container: 'container',
        drop_element: 'container',
        max_file_size: '100mb',
        flash_swf_url: 'js/plupload/Moxie.swf',
        dragdrop: true,
        chunk_size: '4mb',
        uptoken:'um6IEH7mtwnwkGpjImD08JdxlvViuELhI4mFfoeL:79ApUIePTtKIdVGDHJ9D9BfBnhE=:eyJzY29wZSI6ImphdmFkZW1vIiwiZGVhZGxpbmUiOjE0NTk4ODMyMzV9Cg==',
        // uptoken_url: $('#uptoken_url').val(),  //当然建议这种通过url的方式获取token
        domain: $('#domain').val(),
        auto_start: false,
        init: {
            'FilesAdded': function(up, files) {
                $('table').show();
                $('#success').hide();
                plupload.each(files, function(file) {
                    var progress = new FileProgress(file, 'fsUploadProgress');
                    progress.setStatus("等待...");
                });
            },
            'BeforeUpload': function(up, file) {
                var progress = new FileProgress(file, 'fsUploadProgress');
                var chunk_size = plupload.parseSize(this.getOption('chunk_size'));
                if (up.runtime === 'html5' && chunk_size) {
                    progress.setChunkProgess(chunk_size);
                }
            },
            'UploadProgress': function(up, file) {
                var progress = new FileProgress(file, 'fsUploadProgress');
                var chunk_size = plupload.parseSize(this.getOption('chunk_size'));

                progress.setProgress(file.percent + "%", file.speed, chunk_size);
            },
            'UploadComplete': function() {
                $('#success').show();
            },
            'FileUploaded': function(up, file, info) {
                var progress = new FileProgress(file, 'fsUploadProgress');
                progress.setComplete(up, info);
            },
            'Error': function(up, err, errTip) {
                $('table').show();
                var progress = new FileProgress(err.file, 'fsUploadProgress');
                progress.setError();
                progress.setStatus(errTip);
            }
        }
    });

    uploader.bind('FileUploaded', function() {
        console.log('hello man,a file is uploaded');
    });

    $('#up_load').on('click', function(){
        uploader.start();
    });
    $('#stop_load').on('click', function(){
        uploader.stop();
    });

    var Q2 = new QiniuJsSDK();
    var uploader2 = Q2.uploader({
        runtimes: 'html5,flash,html4',
        browse_button: 'pickfiles2',
        container: 'container2',
        drop_element: 'container2',
        max_file_size: '100mb',
        flash_swf_url: 'js/plupload/Moxie.swf',
        dragdrop: true,
        chunk_size: '4mb',
        uptoken:'um6IEH7mtwnwkGpjImD08JdxlvViuELhI4mFfoeL:79ApUIePTtKIdVGDHJ9D9BfBnhE=:eyJzY29wZSI6ImphdmFkZW1vIiwiZGVhZGxpbmUiOjE0NTk4ODMyMzV9Cg==',
        // uptoken_url: $('#uptoken_url').val(),  //当然建议这种通过url的方式获取token
        domain: $('#domain').val(),
        auto_start: false,
        init: {
            'FilesAdded': function(up, files) {
                $('table').show();
                $('#success').hide();
                plupload.each(files, function(file) {
                    var progress = new FileProgress(file, 'fsUploadProgress');
                    progress.setStatus("等待...");
                });
            },
            'BeforeUpload': function(up, file) {
                var progress = new FileProgress(file, 'fsUploadProgress');
                var chunk_size = plupload.parseSize(this.getOption('chunk_size'));
                if (up.runtime === 'html5' && chunk_size) {
                    progress.setChunkProgess(chunk_size);
                }
            },
            'UploadProgress': function(up, file) {
                var progress = new FileProgress(file, 'fsUploadProgress');
                var chunk_size = plupload.parseSize(this.getOption('chunk_size'));

                progress.setProgress(file.percent + "%", file.speed, chunk_size);
            },
            'UploadComplete': function() {
                $('#success').show();
            },
            'FileUploaded': function(up, file, info) {
                var progress = new FileProgress(file, 'fsUploadProgress');
                progress.setComplete(up, info);
            },
            'Error': function(up, err, errTip) {
                $('table').show();
                var progress = new FileProgress(err.file, 'fsUploadProgress');
                progress.setError();
                progress.setStatus(errTip);
            }
        }
    });

    uploader2.bind('FileUploaded', function() {
        console.log('hello man 2,a file is uploaded');
    });
    $('#up_load2').on('click', function(){
        uploader2.start();
    });
    $('#stop_load2').on('click', function(){
        uploader2.stop();
    });

相应的 index.html 文件加入相关按钮:

代码语言:javascript
复制
<div id="container">
        <a class="btn btn-default btn-lg " id="pickfiles" style="width:160px" href="#" >
            <i class="glyphicon glyphicon-plus"></i>
            <span>选择文件</span>
        </a>

        <a class="btn btn-default btn-lg " id="up_load" style="width:160px" href="#" >
            <span>确认上传</span>
        </a>  

        <a class="btn btn-default btn-lg " id="stop_load" style="width:160px" href="#" >
            <span>暂停上传</span>
        </a> 
    </div>

<div id="container2">
        <a class="btn btn-default btn-lg " id="pickfiles2" style="width:160px" href="#" >
            <i class="glyphicon glyphicon-plus"></i>
            <span>选择文件</span>
        </a>

        <a class="btn btn-default btn-lg " id="up_load2" style="width:160px" href="#" >
            <span>确认上传</span>
        </a>  

        <a class="btn btn-default btn-lg " id="stop_load2" style="width:160px" href="#" >
            <span>暂停上传</span>
        </a> 
    </div>
</div>

以上是我遇见的问题。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017/07/07 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档