前端(react)上傳到阿里雲OSS儲存 例項

Lewyon發表於2022-03-18

需求背景

由於現有的後臺管理系統,上傳的視訊越來越大,加上上傳視訊較慢,後端小哥提出直接從前端上傳視訊或者其他檔案到阿里雲OSS儲存。

  • 阿里雲OSS

阿里雲OSS文件介紹,這裡不做過多贅述

安裝

原本在最開始的時候,是使用node版本的SDK,最開始使用的[nodejs版本]

程式碼如下

async function put() {
      try {
        let result = await client.put('qq.mp4', fileObj);
        console.log(result);
      } catch (err) {
        console.log(keyObject.AccessKeyId);
        console.log(keyObject.AccessKeySecret);
        console.log(keyObject.SecurityToken);

        console.log(err);
      }
    }
    put();

開始上傳圖片的時候還沒有翻車,但是上傳超過30多M的時候,就翻車了,在阿里雲OSS後臺檢視檔案大小為0KB

本來是想用fs模組來操作檔案的,但是發現fs在瀏覽器端,沒法兒使用所以就放棄了nodejs版本的SDK

browser版本

後面仔細查閱文件, 發現browser版本SDK有一個片段上傳的文件,於是就採用了[browser]版本。

使用 browser版本的SDK支援片段上傳,同時可以通過片段上傳返回回來的進度,製作進度條提示,方便操作業務邏輯

let ossConfig = {
      region: 'oss-cn-hangzhou',
      //雲賬號AccessKey有所有API訪問許可權,建議遵循阿里雲安全最佳實踐,部署在服務端使用RAM子賬號或STS,部署在客戶端使用STS。
      accessKeyId: keyObject.AccessKeyId,
      accessKeySecret: keyObject.AccessKeySecret,
      stsToken: keyObject.SecurityToken,
      bucket: 'wesmart-app'
    }

let tempCheckpoint;

    // 定義上傳方法。
    async function multipartUpload() {
      try {
        // object-key可以自定義為檔名(例如file.txt)或目錄(例如abc/test/file.txt)的形式,實現將檔案上傳至當前Bucket或Bucket下的指定目錄。
        let result = await client.multipartUpload('02', fileObj, {
          progress: function (p, checkpoint) {
            // 斷點記錄點。瀏覽器重啟後無法直接繼續上傳,您需要手動觸發上傳操作。
            tempCheckpoint = checkpoint;
            console.log(p);
            console.log(checkpoint);
          },
          mime: 'video/mp4'
        })
      } catch (e) {
        console.log(e);
      }
    }
  • client.multipartUpload方法
  1. 第一個引數為自定義的上傳檔案的名稱,建議使用時間戳進行字尾命名,保證檔案的唯一性,不會被覆蓋

  2. 第二個引數為檔案 回撥函式progress,可以檢視上傳的進度以及檔案的相關資訊

注意事項

上面需要的物件欄位可以通過阿里雲後臺OSS進行檢視,在開發的過程中,個人建議通過請求後端返回的相關key值進行操作

在上傳程式碼的時候,使用的put請求,而且剛開始會報錯跨域的問題,需要在阿里雲OSS進行配置允許請求

Exresponse Header設定為etag

原始碼

import React, { useState, useEffect } from 'react';
import axios from "axios";
const OSS = require('ali-oss');
class Example extends React.Component {
  state = {
    count: 0,
    keyObject: {},
    upfile: "",
  }
  componentDidMount() {
    this.getData();
  }
  getData() {
    let that = this;
    axios.get('獲取keyId的介面地址')
      .then(function (response) {
        console.log(response);
        let { status, data } = response;
        if (status == 200) {
          that.setState({
            keyObject: data
          });
        }
      })
      .catch(function (error) {
        console.log(error);
      });
  }

  handleUpload() {
    let { keyObject, upfile } = this.state;
    var fileObj = document.getElementById("file").files[0];
    console.log(fileObj);
    console.log(keyObject);
    let ossConfig = {
      region: 'oss-cn-hangzhou',
      //雲賬號AccessKey有所有API訪問許可權,建議遵循阿里雲安全最佳實踐,部署在服務端使用RAM子賬號或STS,部署在客戶端使用STS。
      accessKeyId: keyObject.AccessKeyId,
      accessKeySecret: keyObject.AccessKeySecret,
      stsToken: keyObject.SecurityToken,
      bucket: 'wesmart-app'
    }
    let client = new OSS({
      region: 'oss-cn-hangzhou',
      //雲賬號AccessKey有所有API訪問許可權,建議遵循阿里雲安全最佳實踐,部署在服務端使用RAM子賬號或STS,部署在客戶端使用STS。
      accessKeyId: keyObject.AccessKeyId,
      accessKeySecret: keyObject.AccessKeySecret,
      stsToken: keyObject.SecurityToken,
      bucket: 'wesmart-app'
    });

    // async function put() {
    //   try {
    //     let result = await client.put('qq.mp4', fileObj);
    //     console.log(result);
    //   } catch (err) {
    //     console.log(keyObject.AccessKeyId);
    //     console.log(keyObject.AccessKeySecret);
    //     console.log(keyObject.SecurityToken);

    //     console.log(err);
    //   }
    // }

    // put();


    let tempCheckpoint;

    // 定義上傳方法。
    async function multipartUpload() {
      try {
        // object-key可以自定義為檔名(例如file.txt)或目錄(例如abc/test/file.txt)的形式,實現將檔案上傳至當前Bucket或Bucket下的指定目錄。
        let result = await client.multipartUpload('02', fileObj, {
          progress: function (p, checkpoint) {
            // 斷點記錄點。瀏覽器重啟後無法直接繼續上傳,您需要手動觸發上傳操作。
            tempCheckpoint = checkpoint;
            console.log(p);
            console.log(checkpoint);
          },
          mime: 'video/mp4'
        })
      } catch (e) {
        console.log(e);
      }
    }

    // 開始分片上傳。
    multipartUpload();

    // 暫停分片上傳。
    client.cancel();

    // 恢復上傳。
    let resumeclient = new OSS(ossConfig);
    async function resumeUpload() {
      try {
        let result = await resumeclient.multipartUpload('02', fileObj, {
          progress: function (p, checkpoint) {
            tempCheckpoint = checkpoint;
            console.log(p);
            console.log(checkpoint);
          },
          checkpoint: tempCheckpoint,
          mime: 'video/mp4'
        })
      } catch (e) {
        console.log(e);
      }
    }
    resumeUpload();
  }

  handleChange(e) {
    e.persist();
    this.setState({ upfile: e.target.value });
  }

  render() {
    const { upfile } = this.state;
    return (
      <div>
        <script type="text/javascript" src="http://gosspublic.alicdn.com/aliyun-oss-sdk-x.x.x.min.js"></script>
        <p><input id="file" type="file" onChange={this.handleChange.bind(this)} value={upfile} /></p>
        <button onClick={this.handleUpload.bind(this)}>
          上傳
        </button>
      </div>
    )
  }

}

export default Example;

文章個人部落格地址:前端(react)上傳到阿里雲OSS儲存 例項

相關文章