使用axios上傳檔案到阿里雲物件檔案儲存伺服器oss

懶懶的技術宅發表於2019-02-16

背景

  • OSS可用於圖片、音視訊、日誌等海量檔案的儲存。各種終端裝置、Web網站程式、移動應用可以直接向OSS寫入或讀取資料。OSS支援流式寫入和檔案寫入兩種方式。使用阿里雲oss做檔案儲存的時候,不可避免的涉及到檔案的上傳,大概分為兩種方式:

服務端驗證上傳

  • 先將檔案傳遞到應用伺服器,再由應用伺服器上傳至oss伺服器,這種方式的優點是簡單易懂,nodejs只需要按照文件使用ali-oss中介軟體上傳就行,本文重點不放在這種方式,如果有需要可以私信我。這種方式的缺點是,檔案要先上傳到應用伺服器,再上傳到oss,佔用頻寬資源,過程雖然簡單易於操作但是比較繁瑣。

服務端簽名前端直傳

  • 這種方式是我比較推薦使用的,但是需要自己對移動端進行簽名,官方的例子給出了一個php版本的簽名服務檔案,同時上傳使用的是plupload這個功能強大,但是不支援模組化使用的外掛,於是經過一番琢磨,將php版本的簽名服務改成了js版本,同時提供axios版本的檔案上傳供大家參考,親測可行。

服務程式碼:


const crypto =require(`crypto`)
async getSingature(ctx){
        ctx.status=200;
        const _config={...}//裡面存放阿里雲oss的配置引數,不詳細說明,用的都應該懂
        const OSSAccessKeyID=_config[`spring.aliyun.oss.access-key-id`]
        const OSSAccessKeySecret=_config[`spring.aliyun.oss.access-key-secret`]
        const OSSEndPoint=_config[`spring.aliyun.oss.end-point`]
        const OSSBucketName=_config[`spring.aliyun.oss.bucket-name`];
        let now=new Date();
        const expire=300;
        //簽名有效時間五分鐘,可自行設定
        const end = now.getTime()/1000 + expire;
        //過期時間
        let expiration=new Date((now.getTime()/1000+expire)*1000);
        //oss伺服器時間格式iso
        expiration=expiration.toISOString();
        //上傳目錄
        const dir= ``
        //上傳的限制規則
        const condition=[`content-length-range`,0,1048576000]
        const start=[`start-with`,`key`,dir];
        const conditions=[condition]
        const arr={
            expiration,
            conditions
        }
        //上傳策略(規則物件轉json字串)
        const policy=JSON.stringify(arr);
        //進行base64編碼
        const base64_policy= (new Buffer(policy)).toString(`base64`);
        
        const string_to_sign=base64_policy;
        //使用crypto簽名
        const signature=crypto.createHmac(`sha1`,     OSSAccessKeySecret).update(string_to_sign).digest().toString(`base64`);
        const host="http://"+OSSBucketName+`.`+OSSEndPoint.split(`//`)[1];
        const accessid=OSSAccessKeyID;
        //返回結果給前端
        return {
            accessid,
            signature,
            policy:base64_policy,
            expire:end,
            dir,
            host
        }
    }

前端上傳:
注意:oss一次只能上傳一個檔案(只有一個key),可以迴圈執行post,key為上傳到oss後的檔名。signatureObj這裡是上面nodejs服務端返回的簽名物件

    var file=ducument.getElementById(`file`).files[0] 
    var formData = new FormData();
    formData.append(`key`,`上傳檔名`);
    formData.append(`name`,file.name)
    formData.append(`policy`,signatureObj.policy)
    formData.append(`OSSAccessKeyId`,signatureObj.accessid)
    formData.append(`success_action_status`,`200`)
    formData.append(`callback`,``)
    formData.append(`signature`,signatureObj.signature)
    formData.append(`file`,file.file)
    axios({
    url:url,
    method:`post`,
    data:formdata,
    headers: { `Content-Type`: `multipart/form-data` }
})

相關文章