By using form upload, you can call the PostObject operation to upload objects no larger than 5 GB.

Note For more information about PostObject, see PostObject.


Form upload can be used on HTML web pages to upload objects. A typical scenario is web applications. For example, the following table compares the form upload process with other upload processes on a job-search website.

Other upload methods Form upload
Access process
  1. A website user sends a request to upload a resume.
  2. The website server responds with a resume upload page.
  3. The resume is uploaded to the website server.
  4. The website server uploads the resume to OSS.
  1. A website user sends a request to upload a resume.
  2. The website server responds with a resume upload page.
  3. The resume is uploaded to OSS.
  • The form upload process is easier, because data is directly uploaded to OSS without being forwarded by the website server.
  • In other upload processes, objects are uploaded to the website server first. When a large number of objects are uploaded, the website server must be scaled out. In the form upload process, objects are directly uploaded from the client to OSS. When a large number of objects are uploaded, OSS bears the upload pressure and ensures the service quality.

SDK demo

For more information, see Java SDK.


  • You cannot upload objects larger than 5 GB.
  • Object names must comply with the following naming conventions:
    • Object names must be encoded in UTF-8.
    • Object names must be one byte to 1,023 bytes in length.
    • Object names cannot start with a forward slash (/) or a backslash (\).
  • If you upload a large number of objects with sequential prefixes such as timestamps and letters in the object names, multiple object indexes may be stored in a single partition. If too many requests are sent to query these objects, the responsiveness may be slow. We recommend that you do not upload a large number of objects with sequential prefixes. For more information about how to change sequential prefixes to random prefixes, see OSS performance and scalability best practices.
  • By default, when you upload an object to OSS, the existing object with the same object name will be overwritten. You can use the following methods to protect your objects from being unexpectedly overwritten:
    • Enable versioning

      If versioning is enabled, deleted or overwritten objects are saved as previous versions. You can recover the previous versions at any time. For more information, see Overview.

    • Include a parameter in the upload request header

      Include the x-oss-forbid-overwrite parameter in the form fields of the upload request, and set its value to true. This way, when an object with an object name the same as that of the object you want to upload to OSS already exists, the object cannot be uploaded. OSS returns the FileAlreadyExists error. For more information, see PostObject.

      If this parameter is not included in the request header or the value of this parameter is false, the object with the same object name is overwritten.

Process analysis

  1. Create a POST policy.

    The policy form field of a POST request is used to verify the validity of the request. For example, you can set a policy to specify the size and name of the object to upload, the URL to which the client jumps, and the HTTP status code that the client receives after a successful upload. For more information, see PostObject.

    This following example uses the Python code. The policy is a JSON-formatted string.
    # Configure the expiration time before which website users can upload data to 2115-01-27T10:56:19Z and the maximum size of the object to upload to 104,857,600 bytes. To ensure successful testing, a long expiration period is set, which is not recommended in actual use.
    policy="{\"expiration\":\"2115-01-27T10:56:19Z\",\"conditions\":[[\"content-length-range\", 0, 104857600]]}"
  2. Encode the policy string in Base64.
  3. Use the AccessKey secret of OSS to add a signature to the Base64-encoded policy.
  4. Create an HTML page for upload.
  5. Open the HTML page and select the object to be uploaded.

The following example shows the complete Python sample code.

# 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(, policy, hashlib.sha1).digest())
def get_form(bucket, endpoint, access_key_id, access_key_secret, out):
    # 1 Create a POST policy.
    policy="{\"expiration\":\"2115-01-27T10:56:19Z\",\"conditions\":[[\"content-length-range\", 0, 1048576]]}"
    print("policy: %s" % policy)
    # 2 Encode the policy string in Base64.
    base64policy = convert_base64(policy)
    print("base64_encode_policy: %s" % base64policy)
    # 3 Use the AccessKey secret of OSS to add a signature to the encoded policy.
    signature = get_sign_policy(access_key_secret, base64policy)
    # 4 Create an HTML page for the upload.
    form = '''
        <meta http-equiv=content-type content="text/html; charset=UTF-8">
        <head><title>OSS form upload (by calling the PostObject operation)</title></head>
            <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="">
                <input type="text" name="success_action_status" value="201">
                <input name="file" type="file" id="file">
                <input name="submit" value="Upload" type="submit">
    ''' % (bucket, endpoint, access_key_id, base64policy, signature)
    f = open(out, "wb")
    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 and opts.key and opts.out:
        get_form(opts.bucket, opts.endpoint,, opts.key, opts.out)
        print "python %s --bucket=your-bucket --id=your-access-key-id --key=your-access-key-secret --out=out-put-form-name" % __file__

Save this sample code as and run it by using python

Run the saved file as follows:
python --bucket=Your bucket name --endpoint=Bucket endpoint --id=Your AccessKey ID --key=Your AccessKey secret --out=Output object name
python --bucket=oss-sample --id=tphpxp --key=ZQNJzf4QJRkrH4 --out=post.html
  • In the created form, success_action_redirect value= indicates the web page that appears after the upload succeeds. You can replace it with your own web page.
  • In the created form, success_action_status value=201 indicates that HTTP status code 201 is returned after the upload succeeds. You can change it to another HTTP status code.
  • If the generated HTML page is post.html, open post.html and select the object to upload. In this example, the OSS product page ( appears after the upload succeeds.

Security and authorization

To prevent unauthorized third-party users from uploading data to your bucket, OSS provides bucket- and object-level access control. For more information, see Access control.

To authorize third-party users to upload objects, OSS also provides account-based authorization. For more information, see Authorized third-party upload.