Fusion Upload元件 對接 阿里雲OSS/七牛/又拍

FuisonDesign發表於2019-03-28

BeforeUpload 方法

Upload元件的BeforeUpload方法,是一個十分強大的方法,可以在上傳請求發起之前做一系列的操作行為。從而達到改變請求引數的目的。

beforeUpload 的 Function Signature (實在不知道怎麼翻譯了) 為 Function(file: Object, options: Object) => Boolean/Object/Promise。 說明這個方法接收兩個引數

  1. file,即將上傳的原生File物件
  2. options,上傳的各個引數, 包括
{
    action: "http://xxxxx.xxxx"
    data: {}
    headers: {}
    method: "post"
    name: "file"
    timeout: undefined
    withCredentials: true
}
複製程式碼

返回值也支援多種(Boolean/Object/Promise):

返回值 行為
false 阻止上傳
true 繼續上傳
Object 結構同入參 options 繼續上傳並且把 返回值 merge到 上傳引數中
Promise.reject() 阻斷上傳
Promise.resolve(false) 阻斷上傳
Promise.resolve(true) 繼續上傳
Promise.resolve(data) 結構同入參 options 繼續上傳並且把 Promise返回值 merge到上傳引數中

看起來挺複雜,但是其實內在邏輯就是一個: 返回false就阻止上傳, 返回Object都merge上傳引數,其他返回值直接繼續上傳。返回既可以是直接return,也可以是通過Promise返回值。

有了beforeUpload的能力,就可以用來做很多事情了。

formatter方法

Upload對返回值是有要求的。 只有HTTP狀態碼為2xx,且返回體為

{
     "success": true, //必需
      "message": "上傳成功",  // (非必須)
      "url": "https://img.alicdn.com/tps/TB19O79MVXXXXcZXVXXXXXXXXXX-1024-1024.jpg"             // 返回結果
      "imgURL": "https://img.alicdn.com/tps/TB19O79MVXXXXcZXVXXXXXXXXXX-1024-1024.jpg",         // 圖片預覽地址 (非必須)
      "downloadURL": "https://img.alicdn.com/tps/TB19O79MVXXXXcZXVXXXXXXXXXX-1024-1024.jpg",    // 檔案下載地址 (非必須)
}
複製程式碼

則代表成功。

由於各大雲廠商,對於成功請求成功的定義是不一樣的。所以需要用到Upload元件Upload元件的formatter方法。formatter接收原始的 response,使用者自行把原始response轉化為Uplaod要求的標準response並返回即可。

阿里雲OSS

OSS 是阿里雲提供的檔案儲存服務, 在集團內也是十分常用的一個儲存服務。 目前阿里雲推薦的方式是,Web端簽名直傳OSS。

Fusion Upload元件 對接 阿里雲OSS/七牛/又拍

首先看看文件樣例,對接OSS主要分為三個步驟:

  1. 獲取檔案資訊
  2. 請求上傳引數
  3. 上傳檔案

這樣就又要用到beforeUpload方法了,三個步驟都可以在beforeUpload中完成。假設我們的後端實現和官方Demo一致。官方樣例的上傳引數返回是這樣的:

{
    "accessid": "xxxxxxx",
    "host": "http://post-test.oss-cn-hangzhou.aliyuncs.com",
    "policy": "xxxxxxxxxxxxxxxx",
    "signature": "xxxxxxxxxxxxx",
    "expire": 1546944707,
    "dir": "xxx/xxxx/xx/xx"
}
複製程式碼

前端通過ajaxGetOSSToken函式上面這個資料,那麼beforeUpload就可以這樣寫:

function beforeUpload(file, uploadOptions) {
    // file 原生的File物件,即將被上傳的檔案
    // uploadOptions 是 上傳引數
    let promise = ajaxGetOSSToken(); // 函式自行實現,保證返回一個promise來就可以
    promise = promise.then((data) => {
    	uploadOptions.data = {
    		name: file.filename,
			key: `${data.dir}${file.name}`,
			policy: data.policy,
			OSSAccessKeyId: data.accessid,
			success_action_status: 200
			signature: data.signature
    	};
    	uploadOptions.headers = {'X-Requested-With': null};// 需要跨域上傳的話加這一段
    	uploadOptions.action = data.host;
    	return uploadOptions;
    });

    return promise;
}
複製程式碼
 <Upload
        action="" // 先不填 有服務端返回
        beforeUpload={beforeUpload}
        onChange={onChange}
        onSuccess={onSuccess}
        withCredentials={false} // 這個很重要
    >
        <Button>Upload File</Button>
    </Upload>
複製程式碼

可以上傳檔案到OSS的Upload元件就完成了。

七牛雲端儲存

七牛提供了Form上傳介面與後端生成Token的Java SDK NodeJS SDK。 假設後端返回的資料是這樣的:

{
    "token": "xxxxxxx",
    "key": "xxx/yyyy/zzz/aaa.jpg",
    "host": "http://upload.qiniup.com/"
}
複製程式碼

前端通過ajaxGetOSSToken函式上面這個資料,那麼beforeUpload就可以這樣寫:

function beforeUpload(file, uploadOptions) {
    // file 原生的File物件,即將被上傳的檔案
    // uploadOptions 是 上傳引數
    
    let promise = ajaxGetOSSToken(); // 函式自行實現,保證返回一個promise來就可以
    promise = promise.then((data) => {
    	uploadOptions.data = {
    		token: data.token,
			key: data.key,
    	};
    	uploadOptions.headers = {'X-Requested-With': null};// 需要跨域上傳的話加這一段
    	uploadOptions.action = data.host;
    	return uploadOptions;
    });
    
    return promise;
}
複製程式碼
 <Upload
        action="" // 先不填 有服務端返回
        beforeUpload={beforeUpload}
        onChange={onChange}
        onSuccess={onSuccess}
        withCredentials={false} // 這個很重要
    >
        <Button>Upload File</Button>
    </Upload>
複製程式碼

可以上傳檔案到七牛的Upload元件就完成了。

又拍雲

又拍雲提供Form API,支援大檔案和小檔案上傳,本處以小檔案上傳為例。也給後端生成Token的各種語言的SDK。 假設後端返回的資料是這樣的:

{
    saveKey: "xxxxx",
    policy: "xxxxxx==",
    authorization: "xxxxxxxx",
    bucket: "xxxx",
}
複製程式碼

前端通過ajaxGetOSSToken函式上面這個資料,那麼beforeUpload就可以這樣寫:

function beforeUpload(file, uploadOptions) {
    // file 原生的File物件,即將被上傳的檔案
    // uploadOptions 是 上傳引數
    
    let promise = ajaxGetOSSToken(); // 函式自行實現,保證返回一個promise來就可以
    promise = promise.then((data) => {
    	uploadOptions.data = {
    		'save-key': data.saveKey,
			policy: data.policy,
			authorization: data.authorization,
        expiration: 30,
    	};
    	uploadOptions.headers = {'X-Requested-With': null};// 需要跨域上傳的話加這一段
    	uploadOptions.action = " http://v0.api.upyun.com/" + data.bucket;
    	return uploadOptions;
    });
    return promise;
}
複製程式碼
 <Upload
        action="" // 先不填 有服務端返回
        beforeUpload={beforeUpload}
        onChange={onChange}
        onSuccess={onSuccess}
        withCredentials={false} // 這個很重要
    >
        <Button>Upload File</Button>
    </Upload>
複製程式碼

可以上傳檔案到又拍雲的Upload元件就完成了。

相關文章