使用Qiniu-JavaScript-SDK上傳文件至七牛雲存儲

1、Qiniu-JavaScript-SDK介紹

  基於 JS-SDK 能夠方便的從瀏覽器端上傳文件至七牛雲存儲,並對上傳成功後的圖片進行豐富的數據處理操做。
  JS-SDK 兼容支持 H5 File API 的瀏覽器,在低版本瀏覽器下,須要額外的插件如 plupload,JS-SDK 提供了一些接口能夠結合插件來進行上傳工做。javascript

  Qiniu-JavaScript-SDK 爲客戶端 SDK,沒有包含 token 生成實現,爲了安全,token 建議經過網絡從服務端獲取,具體生成代碼能夠參考服務端 SDK 的文檔。前端

一、參考文檔

  官方API文檔:JavaScript SDKvue

  基於七牛 API 開發的前端 JavaScript SDK 源碼地址:https://github.com/qiniu/js-sdkjava

二、引入(NPM安裝)

  NPM 的全稱是 Node Package Manager,是一個 NodeJS 包管理和分發工具,已經成爲了非官方的發佈 Node 模塊(包)的標準。node

$ npm install qiniu-js

2、vue項目實現  

  建立七牛上傳組件:/src/components/chart/QiniuUpload.vueios

  下面代碼中集成了上傳進度條,及上傳完成提示,還添加了已上傳文件的文件名顯示:git

<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-else>
      {{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
      },
      boxClass: {
        type: String,
        default: ''
      },
      fileName: {
        type: String
      }
    },
    data(){
      return {
        queryInfo: {
          limit: 10,
          offset: 0,
        },
        token: "",
        qiniuKey: "",
        percent: 0,
        percentText: "",
        showProgress: false
      }
    },
    methods: {
      beforeImageUpload(file) {  // 限制圖片格式和大小
        const isPng = file.type === "image/png";
        const isJpeg = file.type === "image/jpeg";
        const isJpg = file.type === "image/jpg";
        const isLt2M = file.size / 1024 / 1024 < 2;
        if (!isPng && !isJpeg && !isJpg) {
          this.$showDialog("警告信息", "上傳圖片只能是 jpg、png、jpeg 格式!");
          return false;    // 等同於retrun false;  不執行
        } else if (!isLt2M) {
          this.$showDialog("警告信息", "上傳圖片大小不能超過2MB!");
          return false;
        } else {
          return true;
        }
      },
      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){
          this.showProgress = true;   // 顯示上傳過程
          //後端獲取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 對象,上傳的文件
            var key = "";
            if (this.filetype === "idCodeImg") {
              // 身份證照片
              if (this.beforeImageUpload(file)) {
                key = this.filetype + '/U' + userno + 'T' + timestamp + '/' + file.name;
              } else {
                return;
              }
            } else if (this.filetype === "cardImg") {
              // 證件照片
              if (this.beforeImageUpload(file)) {
                key = this.filetype + '/U' + userno + 'T' + timestamp + '/' + file.name;
              } else {
                return;
              }
            } else{
              // 課堂附件
              this.$emit('change', file.name);
              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.showProgress = false;
                this.$emit('key', this.qiniuKey);
                this.$emit('url', result.data.url);
              }
            })
          })
        }
      },
      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);
          });
        })
      }
    },
    mounted() {
      this.$pageInit();
      this.fileToken = this.$sessionUser.fetch().fileToken;
    }
  }
</script>

 

二、在父組件中引入七牛上傳組件

  使用props傳遞屬性到子組件。這樣能夠拼接出比較複雜的文件名(key: 文件資源名)。github

<template>
  <div class="app-content">
    <section class="section">
      <v-breadcrumb></v-breadcrumb>
      <div class="section-body">
        <div class="row">
          <div class="col-lg-12">
            <div class="card">
              <div class="card-header">
                <h4>編輯/添加招生學生</h4>
              </div>
              <div class="card-body">
                <div class="row">
                  <div class="col-md-6">
                    <div class="form-group row">
                      <label for="idCardFront" class="col-md-4 col-form-label">身份證正面上傳(頭像)</label>
                      <QiniuUpload id="idCardFront" filetype="idCodeImg" :qiniuUploadDesc="'上傳圖片'" :boxClass="'add-idImg1'"
                                   @url="setFrontUrl" :fileName="queryInfo.idImg1.split('/').pop()">
                        <template slot="uploadTitle">
                        </template>
                      </QiniuUpload>
                    </div>
                    <div class="form-group row">
                      <label for="idCardBack" class="col-md-4 col-form-label">身份證反面上傳(國徽)</label>
                      <QiniuUpload id="idCardBack" filetype="idCodeImg" :qiniuUploadDesc="'上傳圖片'" :boxClass="'add-idImg2'"
                                   @url="setBackUrl" :fileName="queryInfo.idImg2.split('/').pop()">
                        <template slot="uploadTitle">
                        </template>
                      </QiniuUpload>
                    </div>
                  </div>
                  <div class="col-md-6">
                    <div class="form-group row">
                      <label for="cardType" class="col-md-3 col-form-label">學歷證件</label>
                      <div class="col-md-5 m-t-5 m-b-5">
                        <Enums type="card_type" id="cardType" v-model="queryInfo.cardType" placeholder="請選擇證件類型"></Enums>
                      </div>
                    </div>
                    <div class="form-group row">
                      <label for="idCardBack" class="col-md-3 col-form-label">學歷證件上傳</label>
                      <QiniuUpload id="cardImg" filetype="cardImg" :qiniuUploadDesc="'上傳圖片'" :boxClass="'add-cardImg'"
                                   @url="setCardUrl" :fileName="queryInfo.cardImg.split('/').pop()">
                        <template slot="uploadTitle">
                        </template>
                      </QiniuUpload>
                    </div>
                  </div>
                </div>
相關文章
相關標籤/搜索