本文以Node.js語言為例,介紹如何通過Node.js代碼在服務端先完成簽名,並設定上傳回調,然後通過表單直傳資料到OSS。
前提條件
- 應用伺服器對應的網域名稱可通過公網訪問。
- 應用伺服器已經安裝Node.js 8.0以上版本。您可以執行node -v命令驗證Node.js版本。
- 用戶端運行需要瀏覽器支援HTML4、HTML5、Flash、Silverlight。
步驟一:配置應用伺服器
- 下載應用伺服器源碼。
- 本樣本中以Ubuntu 16.04為例,將源碼解壓到/home/aliyun/aliyun-oss-appserver-node.js目錄下。
- 在專案的根目錄下執行npm install。
- 在專案的根目錄下找到源碼檔案
app.js
,修改以下程式碼片段:const config = { // 阿里雲帳號AccessKey擁有所有API的存取權限,風險很高。強烈建議您建立並使用RAM使用者進行API訪問或日常營運,請登入RAM控制台建立RAM使用者。 accessKeyId: 'yourAccessKeyId', accessKeySecret: 'yourAccessKeySecret', // 填寫Bucket名稱。 bucket: 'yourBucket', // 設定上傳回調URL,即回調伺服器位址,用於處理應用伺服器與OSS之間的通訊。OSS會在檔案上傳完成後,把檔案上傳資訊通過此回調URL發送給應用伺服器。例如callbackUrl填寫為https://oss-demo.aliyuncs.com:23450。 callbackUrl: 'yourCallBackUrl', // 當您需要設定上傳到OSS檔案的首碼時,請配置此項,否則置空即可。 dir: 'yourPrefix' }
步驟2:配置用戶端
- 下載用戶端源碼。
- 解壓檔案。本例以解壓到
D:\aliyun\aliyun-oss-appserver-js
目錄為例。 - 在該目錄下開啟
upload.js
檔案,找到以下代碼語句:// serverUrl是使用者用來擷取簽名直傳和Policy等資訊的應用伺服器URL。請將下面的IP和Port配置為您自己的真實資訊。 serverUrl = 'http://88.88.88.88:8888'
- 將
severUrl
改為應用伺服器的地址。例如,您可以將其修改為serverUrl = 'https://oss-demo.aliyuncs.com:23450'
,用戶端可通過該地址擷取簽名直傳和Policy等資訊。
步驟三:配置跨域規則
用戶端進行表單直傳到OSS時,會從瀏覽器向OSS發送帶有Origin
的請求訊息。OSS對帶有Origin
頭的請求訊息會進行跨域規則(CORS)的驗證。因此需要為Bucket設定跨域規則以支援Post方法。
步驟四:體驗上傳回調
- 在應用伺服器根目錄下,執行npm run server命令啟動應用伺服器。
- 在PC端的用戶端源碼目錄中,開啟index.html檔案。
- 單擊選擇檔案,選擇指定類型的檔案,單擊開始上傳。上傳成功後,顯示回調伺服器返回的內容。
附錄:應用伺服器核心代碼解析
應用伺服器源碼包含了簽名直傳服務以及上傳回調服務的完整範例程式碼。以下僅提供核心程式碼片段,如需瞭解這兩個功能的完整實現,請參見應用伺服器源碼(Node.js版本)。
- 簽名直傳服務 擷取應用伺服器簽名參數和回調伺服器位址的程式碼片段如下:
app.get("/", async (req, res) => { const client = new OSS(config); const date = new Date(); date.setDate(date.getDate() + 1); const policy = { expiration: date.toISOString(), //設定Unix時間戳記(自UTC時間1970年01月01號開始的秒數),用於標識該請求的逾時時間。 conditions: [ ["content-length-range", 0, 1048576000], //設定上傳檔案的大小限制。 ], }; // 設定跨域資源共用規則CORS。 res.set({ "Access-Control-Allow-Origin": req.headers.origin || "*", "Access-Control-Allow-Methods": "PUT,POST,GET", }); // 調用SDK擷取簽名。 const formData = await client.calculatePostSignature(policy); // 填寫Bucket外網網域名稱。 const host = `http://${config.bucket}.${ (await client.getBucketLocation()).location }.aliyuncs.com`.toString(); // 上傳回調。 const callback = { callbackUrl: config.callbackUrl,// 設定回調請求的伺服器位址,例如http://oss-demo.aliyuncs.com:23450。 callbackBody:// 設定回調的內容,例如檔案ETag、資源類型mimeType等。 "filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}", callbackBodyType: "application/x-www-form-urlencoded",// 設定回調的內容類型。 }; // 返回參數。 const params = { expire: moment().add(1, "days").unix().toString(), policy: formData.policy, // 從OSS伺服器擷取到的Policy。 signature: formData.Signature, // 從OSS伺服器擷取到的Signature。 accessid: formData.OSSAccessKeyId,// 從OSS伺服器擷取到的OSS AccessKeyId。 host, // 格式為https://bucketname.endpoint,例如https://bucket-name.oss-cn-hangzhou.aliyuncs.com。 callback: Buffer.from(JSON.stringify(callback)).toString("base64"),// 通過Buffer.from對JSON進行Base64編碼。 dir: config.dir,// 擷取到的檔案首碼。 }; res.json(params); });
- 上傳回調服務
上傳回調服務響應OSS發送給應用伺服器的POST訊息,程式碼片段如下:
// 監聽/result路徑下的POST請求。 app.post("/result", (req, res) => { // 通過Base64解碼公開金鑰地址。 const pubKeyAddr = Buffer.from( req.headers["x-oss-pub-key-url"], "base64" ).toString("ascii"); // 判斷要求標頭中的x-oss-pub-key-url是否來源於OSS伺服器。 if ( !pubKeyAddr.startsWith("https://gosspublic.alicdn.com/") && !pubKeyAddr.startsWith("https://gosspublic.alicdn.com/") ) { console.log("pub key addr must be oss addrss"); // 如果x-oss-pub-key-url不是來源於OSS伺服器,則返回“verify not ok”,表明回調失敗。 res.json({ Status: "verify not ok" }); } // 如果x-oss-pub-key-url來源於OSS伺服器,則返回“Ok”,表明回調成功。 res.json({ Status: "Ok" }); });
有關上傳回調的更多資訊,請參見Callback。