金山云KS3 浏览器通过ks3-js-sdk上传文件

344 阅读1分钟

本文将重点介绍如何通过ks3-js-sdk上传文件,目前主要有两种方式:Post和Put。其中Post方式使用于存在兼容性问题的情况,传参较复杂,对于采用sdk方式的上传,这里推荐使用Put方式。因ak、sk放在前端代码中存在安全性问题,所以这里建议在自己的应用服务器端部署STS服务,前端通过接口获取临时角色。下面将以此方式作为示例的前提进行介绍:

后端服务(以nodejs为例)

var KS3 = require('ks3')
var STS = KS3.STS
// npm install connect-multiparty -S
var multipart = require('connect-multiparty');  
var multipartMiddleware = multipart(); 

const ak = ’<your ak>‘
const sk = '<your sk>'
const endpoint = '<your endpoint>'
const RoleKrn = '<replace your RoleKrn>'

/**
 * 返回临时身份
 */
app.get('/getRole', (req, response) => {
  var client = new STS({
    ak,
    sk,
  });

  client.assumeRole({
    roleKrn: RoleKrn,
    roleSessionName: 'test' // 可按业务需求自定义
  }).then(result => {
    console.log(result)
    const res = JSON.parse(result)
    const credentials = res.AssumeRoleResult.Credentials
    const json = {
      AccessKeyId: credentials.AccessKeyId,
      AccessKeySecret: credentials.SecretAccessKey,
      SecurityToken: credentials.SecurityToken,
      Expiration: credentials.Expiration,
      BucketName: bucketName,
      Endpoint: endpoint
    }

    response.json(json);
  }).catch(err => {
    console.log(err);
    response.status(400).json(err.message);
  })
})

前端代码(以Vue为例)

html页面

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>KS3-SDK-Vue-demo</title>
  <script src="./vue.min.js"></script>
  <!-- 使用时替换为当前最新版sdk -->
  <script src="./ks3-js-sdk.min.js"></script>
  <!-- 自行封装的请求类,参考https://gitee.com/studyNeo/common-libs/blob/master/request.js,亦可自行替换 -->
  <script src="./request.js"></script>
</head>
<body>
  <div id="app">
    <div style="margin: 10px 0;">
      <span style="display: inline-block;padding: 5px;">
        <button @click="putUploadFileClick" style="margin: 0 10px 0 0;">Put上传文件</button>
        <input type="file" style="display: none;" @change="putUploadChange" class="sts-file-select">
      </span>
      <span v-show="result">{{ result }}</span>
    </div>
  </div>
</body>
<script>
 (function() {
    const vm = new Vue({
      el: '#app',
      data() {
        return {
          uploadParams: {}, // 上传参数
          ks3: '',
          result: ''
        }
      },
      async created() {
        this.initKs3Client()
      },
      methods: {
          //基于xmlhttprequest改造
        fetch (method, url, data) {
          return new Promise((resolve, reject) => {
            request.send({
              type: method,
              url,
              data,
              success: function (json) {
                resolve(json)
              },
              error: function (err) {
                reject(err)
              }
            })
          })
        },
        async initKs3Client () {
            try {
                const data = await this.fetch('get', 'http://localhost:3000/getRole', '')
                const obj = JSON.parse(data)
                const { AccessKeyId, AccessKeySecret, Expiration, SecurityToken, BucketName, Endpoint } = obj
                this.ks3 = new KS3({
                    AK: AccessKeyId,
                    SK: AccessKeySecret,
                    bucket: BucketName,
                    domain: Endpoint,
                    securityToken: SecurityToken
                });
            } catch(e) {
                console.error(e)
            }
        },
        putUploadFileClick() {
          document.querySelectorAll('.sts-file-select')[0].click();
        },
        putUploadChange (e) {
          this.uploadChange(e)
        },
        // 上传
        uploadChange(events) {
          const files = events.currentTarget.files;
          const file = files[0]
          const objectKey = `web-${Math.floor(Math.random()*10)}-` + file.name
          const date = (new Date()).toUTCString()

          const self = this
          this.ks3.putObject({
            'key': objectKey,
            'file': file,
            date,
            type: file.type,
            'progress': function(e1,e2){
                console.log('putObject progress:', e1, e2)
            }
          }, function(err, data){
              if(err){
                console.error('putObject err:', err.error.Error);
                self.result = err.error.Error
                return
              }
              if (data.statusCode == 200) {
                self.result = '上传成功'
              }
          })
        }
      },
    });
  })();

</script>
</html>

运行结果:

image.png