文档

表单上传

更新时间:

表单上传是指使用OSS API中的PostObject请求来完成Object的上传,上传的Object不能超过5 GB。

使用场景

表单上传适用于在HTML网页中上传Object,比较常见的场景是网站应用,以招聘网站为例:

不使用表单上传

表单上传

  1. 网站用户上传简历。

  2. 网站服务器回应上传页面。

  3. 简历被上传到网站服务器。

  4. 网站服务器再简历上传到OSS。

  1. 网站用户上传简历。

  2. 网站服务器回应上传页面。

  3. 简历上传到OSS。

  • 从流程上看,使用表单上传不需要通过网站服务器流程转发到OSS的过程,更加方便。

  • 从架构上看,如果不使用表单上传,当上传量过大时,需要扩容网站服务器。采用表单上传后,直接从客户端上传数据到OSS,上传量过大时,由OSS来保障服务质量。

注意事项

  • 文件大小限制

    表单上传的Object的大小不能超过5 GB。超过5 GB的Object上传请使用分片上传

  • Object命名规则

    • 使用UTF-8编码。

    • 长度必须在1~1023字符之间。

    • 不能以正斜线(/)或者反斜线(\)字符开头。

  • 降低PUT类请求费用

    如果要上传的文件数量较多,直接指定上传的文件类型为深度冷归档类型会造成较高的PUT类请求费用。建议您先将文件的存储类型指定为标准存储进行上传,然后通过生命周期规则将其转储为深度冷归档类型,从而降低PUT类请求费用。

  • 上传的安全及授权

    为了防止第三方未经授权往您的Bucket里上传数据,OSS提供了Bucket和Object级别的访问权限控制。更多信息,请参见访问控制概述

    为了授权给第三方上传,OSS还提供了账号级别的授权。具体操作,请参见授权给第三方上传

  • 上传性能调优

    如果您在上传大量Object时,在命名上使用了顺序前缀(如时间戳或字母顺序),可能会出现大量Object索引集中存储于存储空间中某个特定分区的情况,此时如果您的请求速率过大,会导致请求速率下降。建议您在上传大量Object时,不要使用顺序前缀的Object名称,而是将顺序前缀改为随机性前缀。具体操作,请参见OSS性能与扩展性最佳实践

  • 防止同名Object被覆盖

    OSS的简单上传默认会覆盖同名Object, 为防止Object被意外覆盖,您可以通过以下方式保护您的Object:

    • 开启版本控制功能

      开启版本控制功能后,被覆盖的Object会以历史版本的形式保存下来。您可以随时恢复历史版本Object。更多信息,请参见版本控制概述

    • 在上传请求中携带禁止覆盖同名Object的参数

      在上传请求的Header中携带参数x-oss-forbid-overwrite,并指定其值为true。当您上传的Object在OSS中存在同名Object时,该Object会上传失败,并返回FileAlreadyExists错误。当不携带此参数或此参数的值为false时,同名Object会被覆盖。

操作步骤

使用阿里云SDK

以下为Python SDK表单上传的完整流程。

  1. 编写以下代码。

    #coding=utf8
    import hashlib
    import base64
    import hmac
    from optparse import OptionParser
    
    def convert_base64(input):
        return base64.b64encode(input.encode(encoding='utf-8')).decode('utf-8')
    
    def get_sign_policy(key, policy):
        return base64.b64encode(hmac.new(key.encode(encoding='utf-8'), policy.encode(encoding='utf-8'), hashlib.sha1).digest()).decode('utf-8')
    
    def get_form(bucket, endpoint, access_key_id, access_key_secret, out):
        # 构建一个Post Policy。
        # Post请求的Policy表单域用于验证请求的合法性。例如可以指定上传的大小,可以指定上传的Object名称,上传成功后客户端跳转到的URL以及上传成功后客户端收到的状态码等。
        policy="{\"expiration\":\"2115-01-27T10:56:19Z\",\"conditions\":[[\"content-length-range\", 0, 1048576]]}"
        print("policy: %s" % policy)
        # 将Policy字符串进行base64编码。
        base64policy = convert_base64(policy)
        print("base64_encode_policy: %s" % base64policy)
        # 使用OSS的AccessKeySecret对编码后的Policy进行签名。
        signature = get_sign_policy(access_key_secret, base64policy)
        # 构建上传的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="https://oss.aliyun.com">
                    # 设置上传成功后返回的状态码为201,状态码支持自定义。
                    <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.encode(encoding='utf-8'))
        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__)
  2. 将以上代码保存为postobject.py文件。

  3. 在Python项目路径下使用python postobject.py运行示例代码,并配置以下各项参数。

    配置示例如下:

    python postobject.py --bucket=examplebucket --endpoint=oss-cn-hangzhou.aliyuncs.com --id=LTAI5t7h6SgiLSganP2m**** --key=KZo149BD9GLPNiDIEmdQ7dyNKG**** --out=post.html

    参数说明如下:

    参数

    说明

    --bucket

    填写Bucket名称。

    --endpoint

    填写Bucket所在地域对应的Endpoint。

    --id

    访问OSS服务的AccessKey ID。

    --key

    访问OSS服务的AccessKey Secret。

    --out

    输出的文件名称。

  4. 打开post.html,选择待上传的文件,然后单击Upload

    上传成功后,自动跳转至示例代码中指定的页面。

使用REST API

如果您的程序自定义要求较高,您可以直接发起REST API请求。直接发起REST API请求需要手动编写代码计算签名。更多信息,请参见PostObject

  • 本页导读 (1)
文档反馈