一、Qiniu-JavaScript-SDK介绍
基于 JS-SDK 可以方便的从浏览器端上传文件至七牛云存储,并对上传成功后的图片进行丰富的数据处理操作。
JS-SDK 兼容支持 H5 File API 的浏览器,在低版本浏览器下,需要额外的插件如 plupload,JS-SDK 提供了一些接口可以结合插件来进行上传工作。
Qiniu-JavaScript-SDK 为客户端 SDK,没有包含 token
生成实现,为了安全,token
建议通过网络从服务端获取,具体生成代码可以参考服务端 SDK 的文档。
1、参考文档
官方API文档:JavaScript SDK
基于七牛 API 开发的前端 JavaScript SDK 源码地址:https://github.com/qiniu/js-sdk
2、引入(NPM安装)
NPM 的全称是 Node Package Manager,是一个 NodeJS 包管理和分发工具,已经成为了非官方的发布 Node 模块(包)的标准。
$ npm install qiniu-js
二、javascript项目实现
创建七牛上传组件:hsedu_mgr/src/components/chart/QiniuUpload.vue
下面代码中集成了上传进度条,及上传完成提示
<template> <div class="ft-plant-upload-button" :class="boxClass"> <Button class="upload-btn" type="ghost" icon="ios-cloud-upload-outline" :disabled="percent > 0 && percent < 100" @click="zh_uploadFile">{{qiniuUploadDesc}}</Button> <div class="progress-wraper" v-if="showProgress"> <div class="progress" v-if="percent > 0 && percent < 100"> <div class="progress-bar" role="progressbar" aria-valuemin="0" aria-valuemax="100" :style="{width: percent+'%'}"> </div> </div> <div class="precent" v-if="percent > 0 && percent < 100"> {{percent || 0 }}% </div> </div> <div class="file-name" v-if="percent == 100">{{fileName}}</div> <input type="file" ref="evfile" @change="zh_uploadFile_change" style="display:none"> <input type="hidden" :value="qiniuKey"> </div> </template> <script> import * as qiniu from "qiniu-js" export default { name: "QiniuUpload", props: { // 子组件的props选项 qiniuUploadDesc: { type: String, default: '上传文件' }, classroomUpload: { default: '未知classroom' }, filetype: { type: String }, showProgress: { type: Boolean, default: false }, boxClass: { type: String, default: '' } }, data(){ return { queryInfo: { limit: 10, offset: 0, }, token: "", qiniuKey: "", percent: 0, percentText: '', fileName: '' } }, methods: { httpGetList: function () { var self = this; this.$httpGet(this.$http, "users/dataController/getUploadToken", this.$trimJson(self.queryInfo), function (ret) { console.log('ret', ret.token); return ret.token; }); }, //选择上传文件 zh_uploadFile(){ this.$refs.evfile.click(); }, //选择文件后触发的事件 zh_uploadFile_change(evfile){ if (evfile){ //后端获取token this.getQiniuToken().then(res=>{ console.log('res', res); var uptoken = res; var userno = this.$sessionUser.fetch().userno; var timestamp = Date.parse(new Date()); // 时间戳 var file = evfile.target.files[0]; //Blob 对象,上传的文件 this.fileName = file.name; var key = this.filetype + '/' +this.classroomUpload + '/U' + userno + 'T' + timestamp + '.' + file.name.split('.').pop(); // 上传后文件资源名,以设置的 key 为主,如果 key 为 null 或者 undefined,则文件资源名会以 hash 值作为资源名。 let config = { useCdnDomain: true, // 表示是否使用 cdn 加速域名,为布尔值,true 表示使用,默认为 false。 region: qiniu.region.z1 // 上传域名区域(z1为华北),当为 null 或 undefined 时,自动分析上传域名区域 }; let putExtra = { fname: "", // 文件原文件名 params: {}, // 放置自定义变量: 'x:name': 'sex' mimeType: null // 限制上传文件类型,为 null 时表示不对文件类型限制;限制类型放到数组里: ["image/png", "image/jpeg", "image/gif"] }; // observable是一个带有 subscribe 方法的类实例 var observable = qiniu.upload(file, key, uptoken, putExtra, config); var subscription = observable.subscribe({ // 上传开始 next: (result) => { // 接收上传进度信息,result是带有total字段的 Object // loaded: 已上传大小; size: 上传总信息; percent: 当前上传进度 console.log(result); // 形如:{total: {loaded: 1671168, size: 2249260, percent: 74.29856930723882}} this.percent = result.total.percent.toFixed(0); }, error: (errResult) => { // 上传错误后失败报错 console.log(errResult) }, complete: (result) => { // 接收成功后返回的信息 console.log(result); // 形如:{hash: "Fp5_DtYW4gHiPEBiXIjVsZ1TtmPc", key: "%TStC006TEyVY5lLIBt7Eg.jpg"} this.qiniuKey = result.data.key; this.$emit('key', this.qiniuKey) } }) }) } }, getQiniuToken(){ return new Promise((resolve, reject)=>{ var self = this; this.$httpGet(this.$http, "users/dataController/getUploadToken", this.$trimJson(self.queryInfo), function (ret) { console.log('ret', ret.token); resolve(ret.token); }); }) } } } </script> <style lang="scss" scoped> .ft-plant-upload-button { vertical-align: middle; .progress { width: 85px; height: 7px; vertical-align: middle; display: -webkit-inline-box; display: -ms-inline-flexbox; display: inline-flex; background: silver; -webkit-box-shadow: none !important; box-shadow: none !important; margin-left: 5px; } } .upload-btn { border: 1px solid #5084fe; padding: 5px 23px; outline: none; border-radius: 4px; cursor: pointer; background: #fff; color: #333; } .progress-wraper { display: inline-block; } .progress { width: 85px; height: 7px; vertical-align: middle; display: inline-flex; background:rgba(192,192,192,1); box-shadow: none!important; margin-left: 5px; .progress-bar { display: inline-block; background:rgba(80,132,254,1); } } .precent { display: inline-block; vertical-align: middle; margin-left: 3px; } .file-name { display: inline-block; vertical-align: middle; margin-left: 3px; } .add-courseware { padding-left: 15px; } </style>
2、在父组件中引入七牛上传组件
<div class="form-group row"> <label for="qiniu" class="col-md-3 col-form-label">课件上传</label> <QiniuUpload filetype="courseware" :qiniuUploadDesc="'上传课件'" :classroomUpload="queryInfo.classroomno" :boxClass="'add-courseware'" :showProgress="true" @key="setKey"> <template slot="uploadTitle"> </template> </QiniuUpload> </div> <script> import Breadcrumb from '../chart/Breadcrumb'; import Select2 from '../chart/Select2'; import Enums from '../chart/Enums'; import Upload from "../chart/Upload"; import AddEditMain from '../chart/AddEditMain'; import QiniuUpload from '../chart/QiniuUpload'; export default { name: 'AddClassroomCourseware', components: { 'Breadcrumb': Breadcrumb, 'Select2': Select2, 'Enums': Enums, 'Upload': Upload, 'AddEditMain': AddEditMain, 'QiniuUpload': QiniuUpload }, // 代码略 </script>
使用props传递属性到子组件。这样可以拼接出比较复杂的文件名(key: 文件资源名)。