文档章节

七牛 JSSDK 配置+常见问题

娇娇jojo
 娇娇jojo
发布于 2017/07/07 21:08
字数 2651
阅读 213
收藏 0

作者:汪娇娇

时间: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 。

 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,相当于将这个接口直接暴露出去,存在安全隐患。

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就可以了。

multi_selection: false,

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

在FileAdded函数中处理:

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

 

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

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

在FileAdded函数中处理:

'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

使用方法请参考:

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,绑定自定义的事件触发上传。

auto_start: false,
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、限制上传文件的类型

// 可以使用该参数来限制上传文件的类型,大小等,该参数以对象的形式传入,它包括三个属性:
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函数中做相关处理。

unique_names: false,
save_key: false, 
'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 对象:

$(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 文件加入相关按钮:

<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>

 

以上是我遇见的问题,其他问题可以参考七牛JSSDK官网:

https://developer.qiniu.com/kodo/sdk/1283/javascript#6

© 著作权归作者所有

娇娇jojo
粉丝 190
博文 59
码字总数 64429
作品 0
海淀
私信 提问
nutz微信应用开发项目--nuby

Nutz+easyui+mpsdk4j+七牛云服务微信应用开发项目 实现微信基本的消息互动功能,菜单响应,用户信息同步等 最新的JSSDK功能,如分享,图片上传, 网页授权, 一键关注等 后台管理界面用Easyu...

wendal
2015/06/15
3.7K
1
微信社区BBS系统(java框架)

基于移动互联网浏览器的社区系统程序,针对微信平台特别开发和优化,对于有已认证公众号的客户非常适用,整体界面和上传图片的操作等完全和微信保持一致,又可进一步移植到其他浏览器使用,包...

suheme
2016/05/12
51
0
沙龙报名 | 对话AI专家:深度学习平台的设计与思考

2016-12-09 优达学城Udacity 深度学习(Deep Learning)作为一种基于人工神经网络的无监督学习方法,是近年来兴起的一种新的混合机器学习模型。它在计算机视觉、语言识别、自然语言处理等诸多...

Betty__
2016/12/10
15
0
Linux下备份到腾讯云cos、阿里云oss、七牛云存储脚本工具

Linux下备份到腾讯云cos、阿里云oss、七牛云存储脚本工具 简要说明: 这是一个定时将网站备份的脚本。支持腾讯云、阿里云、七牛云存储。这个脚本的运行环境:CentOS 6-7(64位)、RedHat 6-7(...

一招拜师
2017/11/09
0
0
PHP版微信权限验证配置,音频文件下载,FFmpeg转码,上传OSS和删除转存服务器本地文件

一、概述和通过config接口注入权限验证配置 由于微信的(如:录音文件)上传到微信服务器上,。而我们需要长期保存,我们需要把资源从微信服务器转存到自己服务器,或者阿里云OSS/七牛云。 ...

Jack088
2018/04/14
84
1

没有更多内容

加载失败,请刷新页面

加载更多

parseint和isNaN用法

本文转载于:专业的前端网站➭parseint和isNaN用法 <!doctype html><html><head><meta charset="utf-8"><title>无标题文档</title></head><body><script> var a='12'; alert......

前端老手
17分钟前
2
0
Kylin 精确去重在用户行为分析中的妙用

作者:史少锋,Apache Kylin committer & PMC,2019/10/11 在上次文章《如何在 1 秒内做到大数据精准去重》中,我们介绍了 Apache Kylin 为什么要支持大数据集上的精确去重,以及基于 Bitmap...

ApacheKylin
28分钟前
2
0
学习记录(二) es6基本语法(rest参数,模板化,axios模块,拦截器)

日常学习记录 模块化:把一个大文件分成多个小文件,按照一定规范进行拼接 es5写法: 导出:module.exports = 数据 导入:require("路径") /路径未添加后缀名时 //默认添加.js //把路径作为文件名...

Pole丶逐
32分钟前
2
0
以程序员的角度怎么购买一台「性价比高的电视」

前俩天有小伙伴在我的文章下留言,说能否把 【国内电视机都介绍一下】,今天我已在TV端开发多年的程序员的角度。谈谈已程序员的角度如何购买一台性价比高的电视。 国内大的电视机品牌介绍 长...

我们都很努力着
35分钟前
1
0
PhotoShop 色调:理解直方图/RGB通道信息

一、直方图:图表的形式,展示图像像素分布的情况 1.平均值:表示平均亮度 2.标准偏差值:表示亮度值范围内的中间值 3.像素: 表示用于计算直方图的像素总数 4.色阶:显示指针下面的区域亮度...

东方墨天
41分钟前
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部