To use form upload, you can call the PostObject operation to upload an object whose size does not exceed 5 GB.

Note For more information about the PostObject operation, see PostObject.

Scenarios

You can use form upload on HTML web pages to upload objects. For example, you can use form upload in web applications. The following table describes the comparison between the form upload process and other upload processes on a job-search website.

Upload method 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 Object Storage Service (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, the service quality can be ensured by OSS.

SDK demo

For more information, see Form upload in OSS SDK for Java.

Usage notes

  • Object size

    The size of the object that you can upload by using form upload cannot exceed 5 GB. If the object that you want to upload is larger than 5 GB, use resumable upload. For more information, see Multipart upload and resumable upload.

  • Naming conventions
    • The name must be encoded in UTF-8.
    • The name must be 1 to 1,023 characters in length.
    • The name cannot start with a forward slash (/) or a backslash (\).
  • Performance tuning of object upload

    If you upload a large number of objects with sequential prefixes such as timestamps and letters in the object names, many object indexes may be stored in a single partition. In this case, if you send a large number of requests to query these objects, the latency may increase. 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.

  • Preventing an object that has the same name from being overwritten
    By default, when you upload an object to OSS, the existing object that has the same name is overwritten. You can use the following methods to prevent your objects from being unexpectedly overwritten:
    • Enable versioning

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

    • Add a specific parameter in the upload request

      Include the x-oss-forbid-overwrite parameter in the upload request header and set the value to true. This way, if you upload an object whose name is the same as an existing object, the upload fails and OSS returns the FileAlreadyExists error. If this parameter is not included in the request header or the value of this parameter is set to false, the object that has the same name is overwritten. For more information, see PutObject.

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 configure a policy to specify the size and name of the object that you want to upload, as well as the URL to which the client is redirected and the HTTP status code that the client receives after a successful upload. For more information, see PostObject.

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

The following example shows the complete sample Python 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(hmac.new(key, 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 Add a signature to the Base64-encoded policy by using the AccessKey secret of the account that is used to access OSS.
    signature = get_sign_policy(access_key_secret, base64policy)
    # 4 Create an HTML page for the upload.
    form = '''
    <html>
        <meta http-equiv=content-type content="text/html; charset=UTF-8">
        <head><title>OSS form upload (by calling the PostObject operation)</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__

Save the preceding sample code as post_object.py and run the code by using python post_object.py.

Run the saved file in the following way:
python post_object.py --bucket=Your bucket name --endpoint=Bucket endpoint --id=Your AccessKey ID --key=Your AccessKey secret --out=Output file name
Example:
python post_object.py --bucket=oss-sample --endpoint=oss-cn-hangzhou.aliyuncs.com --id=tphpxp --key=ZQNJzf4QJRkrH4 --out=post.html
Note
  • In the created form, success_action_redirect value=http://oss.aliyun.com specifies the web page that appears if the upload is successful. You can replace this with your web page.
  • In the created form, success_action_status value=201 specifies that HTTP status code 201 is returned if the upload is successful. You can change this to another HTTP status code.
  • If the generated HTML page is post.html, open post.html and select the object that you want to upload. In this example, if the object is successfully uploaded, you are redirected to the OSS product page.

Security and authorization

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

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