华为AppGallery Connect提供了一个云存储(CloudStorage)的服务,号称提供了一个便捷的云端存储服务,利用开发者应用的时候,能够不必关注服务器的部署,间接应用就行。
这个服务近期上线了Web端的JavaScript的SDK,我领先体验试用了一下。也能够下载codelab或者demo自行钻研。

1、环境与利用信息

版本名称集成环境-利用测试设施
"cloudstorage": "1.0.0"Window-Node-v14.15.0 npm v6.14.8 Intellij + VuePC-Chrome

环境:https://developer.huawei.com/consumer/rn/service/josp/agc/index.html

SDK版本:"@agconnect/cloudstorage": "^1.0.0-beta3"

集成SDK命令:npm install --save @agconnect/cloudstorage

2、在AGC上开明云存储:

PS: 云存储服务目前还处于beta状态,应用前应该发邮件去申请开明:
https://developer.huawei.com/consumer/cn/doc/development/AppGallery-connect-Guides/agc-cloudstorage-apply

我的我的项目 下抉择你的开发我的项目,在构建上面,找到云存储服务,点击开明:

没有Web我的项目的话,须要先本人创立一个。

开明服务的时候,须要先配置存储实例,这里按需配置就能够,我就轻易配置一个。

下一步,还须要配置安全策略,这里应用默认的安全策略就好:
PS:默认的状况是,只有通过身份认证的用户能力进行读写。

3、装置开发环境:

1、装置Intellij IDEA:

下载地址:https://www.jetbrains.com/idea/download/#section=windows
装置的时候,记得选for web的 IntelliJ IDEA Ultimate

2、创立vue我的项目

3、编译实现后,生成以下文件:

4、SDK集成

1、关上命令行窗口,进入到我的项目目录下,在我的项目目录下执行以下命令,装置云存储的JS SDK:

npm install --save @agconnect/cloudstorage

装置云存储的JS SDK后,会主动匹配AGC SDK,无需额定装置。

2、利用级src目录下创立名为 “agConnectConfig.js” 的文件,并且将AGC界面上“我的项目设置 > SDK代码片段”中所有内容复制到“agConnectConfig.js”里

留神增加export 参数

3、在我的项目门路下执行npm install命令 装置 package.json 依赖。

5、性能开发

a) 页面布局-新建一个

1、新建一个Page.vue文件,在template便签下增加如下代码布局

<div class = "hello">   <div v-show="!isLogin">     <el-button type="primary" @click="signInAnonymously">Login</el-button>   </div>   <div v-show="isLogin" style="max-width:1600px;margin:auto;">     <h1>AGCCloudStorageDemo</h1>     <div style="display:flex;margin-bottom:30px;">       <el-button type="primary" size="medium" @click="getFileList('')">Get FileList</el-button>       <el-button type="primary" size="medium" @click="getFileListAll('')">         Get FileList All       </el-button>       <el-button type="primary" size="medium" @click="uploadString">         Upload String       </el-button>       <el-upload action :on-change="uploadFile" :auto-upload="false">         <el-button type="primary" size="medium" style="width: 100%;margin-left:10px;">Upload File</el-button>       </el-upload>     </div>     <el-table         ref="multipleTable"         border         size="medium"         :data="list">       <el-table-column           type="selection"           width="55">       </el-table-column>       <el-table-column width="80px" label="index">         <template v-slot="scope">           {{ scope.$index + 1 }}         </template>       </el-table-column>       <el-table-column width="100px" label="type">         <template v-slot="scope">           {{ scope.row.isFile ? 'file' : 'directory' }}         </template>       </el-table-column>       <el-table-column           width="150px"           label="name"           prop="name"           show-overflow-tooltip>       </el-table-column>       <el-table-column label="operation">         <template v-slot="scope">           <el-button               v-if="!scope.row.isFile"               type="success"               size="medium"               @click="getFileList(scope.row)"           >             Get FileList           </el-button>           <el-button               v-if="!scope.row.isFile"               type="success"               size="medium"               @click="getFileListAll(scope.row)"           >             Get FileList All           </el-button>           <el-button               v-if="scope.row.isFile"               type="success"               size="medium"               @click="downloadFile(scope.row)"           >             Download File           </el-button>           <el-button               v-if="scope.row.isFile"               type="success"               size="medium"               @click="getFileMetadata(scope.row)"           >             Get FileMetadata           </el-button>           <el-button               v-if="scope.row.isFile"               type="success"               size="medium"               @click="updateFileMetadata(scope.row)"           >             Update FileMetadata           </el-button>           <el-button v-if="scope.row.isFile" type="danger" size="medium" @click="deleteFile(scope.row)">             Delete File           </el-button>           <el-button type="success" size="medium" @click="toString(scope.row)">             To String           </el-button>         </template>       </el-table-column>     </el-table>   </div> </div>

b) 增加配置依赖 & 初始化

1、在script标签下,增加编译依赖

import agconnect from "@agconnect/api"; import "@agconnect/instance"; import "@agconnect/auth"; import "@agconnect/cloudstorage";

2、 初始化SDK:

import { agConnectConfig } from "../agConnectConfig"; const config = agConnectConfig

c) 前置办法:数据与匿名登录

1、在export default对象内,增加data对象,并且配置如下内容:

data(){   return {     list:[],     isLogin:false,     ref:{}   } },

2、在export default对象内,增加对mounted对象,并且配置如下内容:

mounted(){   agconnect.instance().configInstance(config) },

3、增加次要办法:在export default对象内增加method对象,并且增加匿名登录办法:

methods:{   async signInAnonymously () {     agconnect         .auth()         .signInAnonymously()         .then(() => {           alert('login successfully!')           this.isLogin = true           this.ref = agconnect.cloudStorage().storageReference()         })         .catch(() => {           return Promise.reject('sign in anonymously failed')         })   },

d) 上传文件:

在method对象内,增加如下上传文件的办法:

uploadFile(file) {   const path = 'jssdk/' + file.name   const metadata = {     cacheControl: 'helloworld',     contentDisposition: 'helloworld',     contentEncoding: 'helloworld',     contentLanguage: 'helloworld',     contentType: 'helloworld',     customMetadata: {       hello: 'kitty'     }   }   var uploadTask = this.ref.child(path).put(file.raw, metadata)   this.printUploadPercent(uploadTask) }, printUploadPercent (uploadTask) {   uploadTask.on('state_changed', function (snapshot) {     if(!snapshot){       console.log('Upload Result is null')       return;     }     if(snapshot.totalByteCount == 0){       console.log('Upload File is empty')       return;     }     var progress = (snapshot.bytesTransferred / snapshot.totalByteCount) * 100     console.log('Upload is ' + progress.toFixed(1) + '% done')     switch (snapshot.state) {       case 'paused':         console.log('Upload is paused')         break       case 'running':         console.log('Upload is running')         break       case 'success':         console.log('Upload is success')         break       case 'canceled':         console.log('Upload is canceled')         break       case 'error':         console.log('Upload is error')         break     }   }, function (snapshot) {     switch (snapshot.state) {       case 'paused':         console.log('Upload is paused')         break       case 'running':         console.log('Upload is running')         break       case 'success':         console.log('Upload is success')         break       case 'canceled':         console.log('Upload is canceled')         break       case 'error':         console.log('Upload is error')         break     }   }, function () {     console.log('Upload is success')   }) },

e) 下载文件:

在method对象内,增加如下下载文件的办法:

downloadFile(row) {   const child = this.ref.child(row.path)   child.getDownloadURL().then(function (downloadURL) {     alert(downloadURL)     console.log(downloadURL)   }) },

f) 例举文件,其余性能暂不列举:

在method对象内,增加如下例举文件的办法:

getFileList(row) {   var path = row && row.path ? row.path : '';   const child = this.ref.child(path)   child.list({ maxResults: 5 }).then((res) => {     this.list = [...res.dirList.map(item => { item.isFile = false; item.select = false; return item }), ...res.fileList.map(item => { item.isFile = true; item.select = false; return item })]     this.nextMarker = res.pageMarker     console.log(this.list)   }).catch(err => {     console.log(err)   }) }, getFileListAll(row) {   const child = this.ref.child(row && row.path ? row.path : '')   child.listAll()       .then((res) => {         console.log('res', res)         this.list = [...res.dirList.map(item => { item.isFile = false; item.select = false; return item }), ...res.fileList.map(item => { item.isFile = true; item.select = false; return item })]       })       .catch((err) => {         console.log(err)       }) },

6、性能点验证

1、Web运行前置要求:

1、增加element-ui相干依赖: 在main.js文件内,增加element-ui依赖

import ElementUI from 'element-ui'; import 'element-ui/lib/theme-chalk/index.css'; Vue.use(ElementUI);

2、装置element-ui依赖,应用命令行,在我的项目门路下,执行如下命令装置element-ui依赖:

npm install element-ui -S

装置实现后,package.json文件中,将导入如下内容:

3、在app.vue文件中,配置默认启动的vue:

在template标签下,批改默认启动为创立的page.

<template>   <div id="app">     <Page />   </div> </template>

在script标签下,导入并且批改默认的启动vue.

<script> import Page from './components/Page.vue'  export default {   name: 'App',   components: {     Page   } } </script>

批改当前,后果如下:

2、运行我的项目

在我的项目目录下,执行npm run serve命令启动我的项目,点击local超链接进入我的项目。

3、配置跨域申请:

因为咱们以后应用的是本地的IP,即http://localhost:8080/的地址,与云存储云端进行通信的时候,存在网络跨域,须要先通过Server SDK配置网络跨域的相干参数,否则会呈现如下谬误:

具体NodeJS我的项目的集成,请参照上一篇文档:疾速集成华为AGConnect云存储服务-NodeJS中的形容。

在NodeJS代码中,通过setCorsConfiguration办法配置跨域参数。代码如下:

crossIP();function crossIP() {  const storage = new StorageManagement();  const bucket = storage.bucket(bucketName);   bucket.setCorsConfiguration();  const config = [{    "origins": ["*"],    "methods": ["GET", "POST", "PUT", "DELETE"],  }];   bucket.setCorsConfiguration(config).then(res =>     console.log('bucket.setCors res: ', res)    ).catch(err => {      console.log('bucket.setCors err: ', err)    })}

3、运行界面:须要先登录:

4、获取文件列表:

点击Get FileList,获取文件列表

5、上传文件

点击UpLoad File,抉择相应的文件当前,能够点击界面上的GetFileList All,能够看到通过JSSDK的门路,

点击该门路前方的,Get FileList,能够看到刚刚上传的文件:

6、其余性能就不逐个测试了,各位能够自行验证。

7、总结

仅关注Web端的开发,就能够在web界面上操作我的项目中的文件。再也不必为了服务器的搭建和运维放心,省时省力。而且还提供了相似于管理员模式的web控制台,能够简略直观的对服务器上的文件进行治理。

这个云存储服务,除了最一般的上传下载和删除性能,还包含有列举文件,设置元数据等性能,具体能够看官网文档:

云存储服务开发指南:

https://developer.huawei.com/consumer/cn/doc/development/AppGallery-connect-Guides/agc-cloudstorage-introduction

云存储服务codelab-web:
https://developer.huawei.com/consumer/cn/codelab/CloudStorage-web/index.html#0


原文链接:https://developer.huawei.com/consumer/cn/forum/topic/0204411958886860388?fid=0101271690375130218

原作者:Mayism