Configure forced downloads for OSS objects with a custom domain
When you use a browser to access an OSS object using a custom domain, the object is displayed inline by default if the browser supports its file format. To have the browser download the object as an attachment, you can force a download for a single access request by setting the response-content-disposition field to attachment in a presigned URL. You can also force a download for all access requests by setting the Content-Disposition object metadata to attachment.
Force a download with a presigned URL
OSS console
-
Log on to the OSS console.
In the left-side navigation pane, choose Self-service Tools>Signature Tool.
On the Signature Tool page, click the URL Signature tab.
On the URL Signature panel, configure the following parameters. Keep the default settings for other parameters.
Parameter
Example
Description
Access key ID
LTAI*********************
Enter the access key for the current account, which includes an access key ID and an access key secret. For information about how to create an access key for an Alibaba Cloud account or a RAM user, see Create an AccessKey pair.
Access key secret
KZo1******************
URL
https://example.com/test.txt
Enter the custom domain and the full path of the object.
Bucket Name
examplebucket
Enter the name of the bucket in which the object is stored.
Query parameters
attachment
From the drop-down list, select
response-content-dispositionand set its value to attachment. This prompts the browser to download the object with its original name.Click Generate Link, and then copy the generated signed URL.
Open the signed URL in a browser to download the object.
The Signature Tool supports only V1 signatures.
Alibaba Cloud SDK
The following example shows how to use the Alibaba Cloud SDK for Java:
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.model.GeneratePresignedUrlRequest;
import java.net.URL;
import java.util.*;
import java.util.Date;
public class Demo {
public static void main(String[] args) throws Throwable {
// Set yourEndpoint to the custom domain.
String endpoint = "https://example.com";
// Obtain access credentials from environment variables. Before you run this code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured.
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// Create a ClientBuilderConfiguration instance. You can modify the default parameters based on your requirements.
ClientBuilderConfiguration conf = new ClientBuilderConfiguration();
// Set setSupportCname to true to map the custom domain to the target bucket.
conf.setSupportCname(true);
// Specify the bucket name, for example, examplebucket.
String bucketName = "examplebucket";
// Specify the full path of the object, for example, exampleobject.txt. The full path of the object cannot contain the bucket name.
String objectName = "exampleobject.txt";
// Create an OSSClient instance.
// When the OSSClient instance is no longer needed, call the shutdown method to release resources.
OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider, conf);
try {
// Create a request.
GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, objectName);
// Set HttpMethod to GET.
generatePresignedUrlRequest.setMethod(HttpMethod.GET);
// Set the expiration time for the signed URL in milliseconds. In this example, the expiration time is set to 1 hour.
Date expiration = new Date(new Date().getTime() + 3600 * 1000L);
generatePresignedUrlRequest.setExpiration(expiration);
// Download the object with its original name.
Map<String, String> queryParam = new HashMap<String, String>();
queryParam.put("response-content-disposition", "attachment");
generatePresignedUrlRequest.setQueryParameter(queryParam);
// Generate the signed URL.
URL url = ossClient.generatePresignedUrl(generatePresignedUrlRequest);
System.out.println(url);
} catch (OSSException oe) {
System.out.println("An OSSException means your request reached OSS but was rejected.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (ClientException ce) {
System.out.println("A ClientException means the client had a serious internal problem communicating with OSS, "
+ "such as a network issue.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}Force downloads with object metadata
OSS console
-
Log on to the OSS console.
-
In the left-side navigation pane, click Buckets. On the page that appears, click the name of the target bucket.
In the left-side navigation pane, choose .
In the row that contains the target object, choose .
On the Set Object Metadata panel, set Content-Disposition to attachment, keep the default settings for other parameters, and then click OK.
Access the object in a browser using its URL that contains the custom domain.
If the object's access control list (ACL) is set to public-read or public-read-write, you can access the object using a URL such as
http://example.com/example.jpg. In this URL, example.com is the custom domain, and the object example.jpg is in the bucket's root directory.If the object's ACL is set to private, you must add signature parameters to its URL, for example,
http://example.com/example.jpg?signature-parameters. For more information about how to access a private object using a custom domain, see Access temporary URLs of objects by using custom domain names.
Alibaba Cloud SDK
The following example shows how to use the Alibaba Cloud SDK for Java:
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.GeneratePresignedUrlRequest;
import com.aliyun.oss.model.ObjectMetadata;
import java.io.ByteArrayInputStream;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.file.Paths;
import java.util.Date;
public class Test {
public static void main(String[] args) throws Exception {
// Set yourEndpoint to the custom domain.
String endpoint = "https://example.com";
// To avoid security risks from hard-coded credentials, this example retrieves access credentials from environment variables. Before running this code, make sure the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured.
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// Create a ClientBuilderConfiguration instance. You can modify the default parameters based on your requirements.
ClientBuilderConfiguration conf = new ClientBuilderConfiguration();
// Set setSupportCname to true to map the custom domain to the target bucket.
conf.setSupportCname(true);
// Specify the bucket name, for example, examplebucket.
String bucketName = "examplebucket";
// Specify the full path of the object, excluding the bucket name. Example: testfolder/exampleobject.txt.
String objectName = "testfolder/exampleobject.txt";
// Specify the object content.
String content = "Hello OSS";
// Create an OSSClient instance.
// When the OSSClient instance is no longer needed, call the shutdown method to release resources.
OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider, conf);
try {
// Create object metadata. You can use object metadata to set standard HTTP headers.
ObjectMetadata meta = new ObjectMetadata();
String md5 = BinaryUtil.toBase64String(BinaryUtil.calculateMd5(content.getBytes()));
// Enable MD5 content verification. OSS compares the MD5 hash of the uploaded content with the provided hash. If they do not match, an exception is thrown.
meta.setContentMD5(md5);
// Specify the content type, which determines how browsers handle the file. If not specified, the type is inferred from the file extension. If there is no extension, application/octet-stream is used as the default.
meta.setContentType("text/plain");
// Specify that the downloaded object retains its original name. URL-encode the name if it contains non-ASCII characters.
String fileName = Paths.get(objectName).getFileName().toString();
meta.setContentDisposition("attachment; filename*=UTF-8''" + URLEncoder.encode(fileName, "UTF-8"));
// Set the content length of the object. For stream uploads, this is recommended to avoid caching the entire stream in memory.
// meta.setContentLength(content.length());
// Set the Cache-Control header to specify caching behavior.
// meta.setCacheControl("Download Action");
// Set the Expires header with a GMT timestamp for cache expiration.
// meta.setExpirationTime(DateUtil.parseIso8601Date("2025-10-12T00:00:00.000Z"));
// Set a custom header.
// meta.setHeader("yourHeader", "yourHeaderValue");
// Upload the object.
ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content.getBytes()), meta);
// Verify that the URL triggers a direct download.
Date expiration = new Date(new Date().getTime() + 3600 * 1000);
GeneratePresignedUrlRequest signRequest = new GeneratePresignedUrlRequest(bucketName, objectName, HttpMethod.GET);
signRequest.setExpiration(expiration);
URL signedUrl = ossClient.generatePresignedUrl(signRequest);
System.out.println(signedUrl);
} catch (OSSException oe) {
System.out.println("An OSSException means your request reached OSS but was rejected.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (ClientException ce) {
System.out.println("A ClientException means the client had a serious internal problem communicating with OSS, "
+ "such as a network issue.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}Related topics
If you want to specify a custom filename for a downloaded object instead of the original object name, see Specify a custom filename for a downloaded OSS object.
If you want a browser to display an object inline instead of downloading it, see How do I configure the preview behavior for an object?.