適用場景

指的是用戶使用OSS API中的Post Object請求來完成Object的上傳,上傳的Object不能超過5GB。非常適合嵌入在HTML網頁中來上傳Object,比較常見的應用場景是網站應用程式,以招聘網站為例子:

不使用表單上傳 表單上傳
流程對比
  1. 網站用戶上傳簡曆
  2. 網站伺服器回應上傳頁面
  3. 簡曆被上傳到網站伺服器
  4. 網站伺服器再將簡曆上傳到OSS
  1. 網站用戶上傳簡曆
  2. 網站伺服器回應上傳頁面
  3. 簡曆上傳到OSS

上傳限制

  • 大小限制:使用表單上傳時,Object不能超過5GB。
  • 命名限制:
    • 使用UTF-8編碼
    • 長度必須在1-1023位元組之間
    • 不能以“/”或者“\”字元開頭

使用表單上傳的好處

  • 從流程上,少了一步轉寄。
  • 從架構上來說,原來的上傳都統一走網站伺服器,上傳量過大時,瓶頸在網站伺服器,可能需要擴容網站伺服器。採用表單上傳後,上傳都是直接從客戶端發送到OSS。上傳量過大時,壓力都在OSS上,由OSS來保障服務品質。

上傳的安全及授權

  • 為了授權給第三方上傳,這裡使用的是Post Policy的機制,詳情請參見PostObject

使用表單上傳的基本步驟

  1. 構建一個Post Policy。

    Post請求的Policy表單域用於驗證請求的合法性。例如可以指定上傳的大小,可以指定上傳的Object名字等,上傳成功後客戶端跳轉到的URL,上傳成功後客戶端收到的狀態碼。具體請參考Post Policy

    例如如下Policy,網站用戶能上傳的過期時間是2115-01-27T10:56:19Z(這裡為了測試成功寫的過期時間很長,實際使用中不建議這樣設定),能上傳的檔案最大為104857600位元組。
    以Python代碼為例子,Policy是json格式的字元串。
     policy="{\"expiration\":\"2115-01-27T10:56:19Z\",\"conditions\":[[\"content-length-range\", 0, 104857600]]}"
  2. 將Policy字元串進行base64編碼。
  3. 用OSS的AccessKeySecret對base64編碼後的Policy進行簽名。
  4. 構建上傳的HTML頁面。
  5. 開啟HTML頁面,選擇檔案上傳。

完整Python程式碼範例:

#coding=utf8
import md5
import hashlib
import base64
import hmac
from optparse import OptionParser
def convert_base64(input):
    return base64.b64encode(input)
def get_sign_policy(key, policy):
    return base64.b64encode(hmac.new(key, policy, hashlib.sha1).digest())
def get_form(bucket, endpoint, access_key_id, access_key_secret, out):
    #1 構建一個Post Policy
    policy="{\"expiration\":\"2115-01-27T10:56:19Z\",\"conditions\":[[\"content-length-range\", 0, 1048576]]}"
    print("policy: %s" % policy)
    #2 將Policy字元串進行base64編碼
    base64policy = convert_base64(policy)
    print("base64_encode_policy: %s" % base64policy)
    #3 用OSS的AccessKeySecret對編碼後的Policy進行簽名
    signature = get_sign_policy(access_key_secret, base64policy)
    #4 構建上傳的HTML頁面
    form = '''
    <html>
        <meta http-equiv=content-type content="text/html; charset=UTF-8">
        <head><title>OSS表單上傳(PostObject)</title></head>
        <body>
            <form  action="http://%s.%s" method="post" enctype="multipart/form-data">
                <input type="text" name="OSSAccessKeyId" value="%s">
                <input type="text" name="policy" value="%s">
                <input type="text" name="Signature" value="%s">
                <input type="text" name="key" value="upload/${filename}">
                <input type="text" name="success_action_redirect" value="http://oss.aliyun.com">
                <input type="text" name="success_action_status" value="201">
                <input name="file" type="file" id="file">
                <input name="submit" value="Upload" type="submit">
            </form>
        </body>
    </html>
    ''' % (bucket, endpoint, access_key_id, base64policy, signature)
    f = open(out, "wb")
    f.write(form)
    f.close()
    print("form is saved into %s" % out)
if __name__ == '__main__':
    parser = OptionParser()
    parser.add_option("", "--bucket", dest="bucket", help="specify ")
    parser.add_option("", "--endpoint", dest="endpoint", help="specify")
    parser.add_option("", "--id", dest="id", help="access_key_id")
    parser.add_option("", "--key", dest="key", help="access_key_secret")
    parser.add_option("", "--out", dest="out", help="out put form")
    (opts, args) = parser.parse_args()
    if opts.bucket and opts.endpoint and opts.id and opts.key and opts.out:
        get_form(opts.bucket, opts.endpoint, opts.id, opts.key, opts.out)
    else:
        print "python %s --bucket=your-bucket --endpoint=oss-cn-hangzhou.aliyuncs.com --id=your-access-key-id --key=your-access-key-secret --out=out-put-form-name" % __file__

將此段代碼保存為post_object.py,然後用python post_object.py來運行。

用法:
python post_object.py --bucket=您的Bucket --endpoint=Bucket對應的OSS網域名稱 --id=您的AccessKeyId --key=您的AccessKeySecret --out=輸出的檔案名
樣本:
python post_object.py --bucket=oss-sample --endpoint=oss-cn-hangzhou.aliyuncs.com --id=tphpxp --key=ZQNJzf4QJRkrH4 --out=post.html
说明
  • 構建的表單中success_action_redirect value=http://oss.aliyun.com 表示上傳成功後跳轉的頁面。可以替換成您自己的頁面。
  • 構建的表單中success_action_status value=201表示的是上傳成功後返回的狀態碼為201。可以替換。
  • 假如指定生成的HTML檔案為post.html,開啟post.html,選擇檔案上傳。在這個例子中如果成功則會跳轉到OSS的首頁面。

功能使用參考

最佳實踐

相關參考連結