如何配置通過自定義域名訪問OSS文件時(shí)實(shí)現(xiàn)強(qiáng)制下載?
通過瀏覽器使用自定義域名訪問OSS上存儲的文件時(shí),如果您的瀏覽器支持預(yù)覽所選的文件格式,則OSS將直接預(yù)覽文件內(nèi)容。如果您希望通過瀏覽器使用自定義域名訪問OSS文件時(shí),以附件形式下載文件,您可以通過預(yù)簽名URL將response-content-disposition字段設(shè)置為attachment來指定單次訪問為強(qiáng)制下載,還可以通過將文件元數(shù)據(jù)Content-Disposition設(shè)置為attachment來指定所有訪問為強(qiáng)制下載。
通過預(yù)簽名URL設(shè)置單次訪問為強(qiáng)制下載
使用OSS控制臺
登錄OSS管理控制臺。
在左側(cè)導(dǎo)航欄,選擇 。
在簽名工具頁面,單擊URL簽名頁簽。
在URL簽名面板,按以下說明填寫各項(xiàng)參數(shù),其他參數(shù)保留默認(rèn)配置。
參數(shù)
示例值
說明
AccessKeyId
LTAI*********************
填寫當(dāng)前賬號的訪問密鑰AccessKey,包括AccessKey ID和AccessKey Secret。使用阿里云賬號或RAM用戶訪問時(shí),AccessKey的獲取方式,請參見創(chuàng)建AccessKey。
AccessKeySecret
KZo1******************
鏈接
https://example.com/test.txt
填寫自定義域名和Object的完整路徑。
Bucket 名稱
examplebucket
輸入Object所在的Bucket名稱。
Query Params
attachment
下拉選擇
response-content-disposition
,取值為attachment,效果是以原文件名的形式下載到瀏覽器指定路徑。單擊生成鏈接,然后復(fù)制右側(cè)的簽名鏈接。
通過瀏覽器打開簽名鏈接,即可實(shí)現(xiàn)下載。
使用阿里云SDK
以Java SDK為例:
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 {
// yourEndpoint填寫自定義域名。
String endpoint = "https://example.com";
// 從環(huán)境變量中獲取訪問憑證。運(yùn)行本代碼示例之前,請確保已設(shè)置環(huán)境變量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// 創(chuàng)建ClientBuilderConfiguration實(shí)例,您可以根據(jù)實(shí)際情況修改默認(rèn)參數(shù)。
ClientBuilderConfiguration conf = new ClientBuilderConfiguration();
// 將CNAME取值設(shè)置為true,用于將自定義域名綁定到目標(biāo)Bucket。
conf.setSupportCname(true);
// 填寫B(tài)ucket名稱,例如examplebucket。
String bucketName = "examplebucket";
// 填寫Object完整路徑,例如exampleobject.txt。Object完整路徑中不能包含Bucket名稱。
String objectName = "exampleobject.txt";
// 創(chuàng)建OSSClient實(shí)例。
OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider, conf);
try {
// 創(chuàng)建請求。
GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, objectName);
// 設(shè)置HttpMethod為GET。
generatePresignedUrlRequest.setMethod(HttpMethod.GET);
// 設(shè)置簽名URL過期時(shí)間,單位為毫秒。本示例以設(shè)置過期時(shí)間為1小時(shí)為例。
Date expiration = new Date(new Date().getTime() + 3600 * 1000L);
generatePresignedUrlRequest.setExpiration(expiration);
// 下載后顯示為原Object名稱。
Map<String, String> queryParam = new HashMap<String, String>();
queryParam.put("response-content-disposition", "attachment");
generatePresignedUrlRequest.setQueryParameter(queryParam);
// 生成簽名URL。
URL url = ossClient.generatePresignedUrl(generatePresignedUrlRequest);
System.out.println(url);
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
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("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}
通過文件元數(shù)據(jù)設(shè)置所有訪問為強(qiáng)制下載
使用OSS控制臺
登錄OSS管理控制臺。
單擊Bucket 列表,然后單擊目標(biāo)Bucket名稱。
在左側(cè)導(dǎo)航欄,選擇 。
在目標(biāo)Object右側(cè)選擇 。
在設(shè)置文件元數(shù)據(jù)面板,將Content-Disposition設(shè)置為attachment,其他參數(shù)保留默認(rèn)配置,然后單擊確定。
在瀏覽器中通過自定義域名以文件URL的形式訪問目標(biāo)文件。
以自定義域名為example.com,Bucket根目錄下的文件名稱為example.jpg為例(文件讀寫權(quán)限為公共讀或者公共讀寫),您可以在瀏覽器中通過自定義域名拼接文件URL的形式(
http://example.com/example.jpg
)訪問目標(biāo)文件。以自定義域名為example.com,Bucket根目錄下的文件名稱為example.jpg為例(文件讀寫權(quán)限為私有),私有文件URL需要添加簽名信息(格式為
http://example.com/example.jpg?簽名參數(shù)
)。關(guān)于在瀏覽器中通過自定義域名訪問私有文件的具體操作,請參見使用自定義域名訪問臨時(shí)文件URL。
使用阿里云SDK
以Java SDK為例:
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.util.Date;
public class Test {
public static void main(String[] args) throws Exception {
// yourEndpoint填寫自定義域名。
String endpoint = "https://example.com";
// 強(qiáng)烈建議不要把訪問憑證保存到工程代碼里,否則可能導(dǎo)致訪問憑證泄露,威脅您賬號下所有資源的安全。本代碼示例以從環(huán)境變量中獲取訪問憑證為例。運(yùn)行本代碼示例之前,請先配置環(huán)境變量。
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// 創(chuàng)建ClientBuilderConfiguration實(shí)例,您可以根據(jù)實(shí)際情況修改默認(rèn)參數(shù)。
ClientBuilderConfiguration conf = new ClientBuilderConfiguration();
// 將CNAME取值設(shè)置為true,用于將自定義域名綁定到目標(biāo)Bucket。
conf.setSupportCname(true);
// 填寫B(tài)ucket名稱,例如examplebucket。
String bucketName = "examplebucket";
// 填寫不包含Bucket名稱在內(nèi)的Object完整路徑,例如testfolder/exampleobject.txt。
String objectName = "testfolder/exampleobject.txt";
// 文件內(nèi)容。
String content = "Hello OSS";
// 創(chuàng)建OSSClient實(shí)例。
OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider, conf);
try {
// 創(chuàng)建上傳文件的元數(shù)據(jù),可以通過文件元數(shù)據(jù)設(shè)置HTTP標(biāo)準(zhǔn)屬性。
ObjectMetadata meta = new ObjectMetadata();
String md5 = BinaryUtil.toBase64String(BinaryUtil.calculateMd5(content.getBytes()));
// 開啟文件內(nèi)容MD5校驗(yàn)。開啟后OSS會(huì)把您提供的MD5與文件的MD5比較,不一致則拋出異常。
meta.setContentMD5(md5);
// 指定上傳的內(nèi)容類型。內(nèi)容類型決定瀏覽器將以什么形式、什么編碼讀取文件。如果沒有指定則根據(jù)文件的擴(kuò)展名生成,如果沒有擴(kuò)展名則為默認(rèn)值application/octet-stream。
meta.setContentType("text/plain");
// 下載后顯示為原Object名稱。如果包含有中文字符,需要進(jìn)行URL編碼。
meta.setContentDisposition("attachment"+ URLEncoder.encode("UTF-8")+";"+URLEncoder.encode("UTF-8"));
// 設(shè)置上傳文件的長度。如超過此長度,則上傳文件會(huì)被截?cái)啵蟼鞯奈募L度為設(shè)置的長度。如小于此長度,則為上傳文件的實(shí)際長度。
// meta.setContentLength(content.length());
// 設(shè)置內(nèi)容被下載時(shí)網(wǎng)頁的緩存行為。
// meta.setCacheControl("Download Action");
// 設(shè)置緩存過期時(shí)間,格式是格林威治時(shí)間(GMT)。
// meta.setExpirationTime(DateUtil.parseIso8601Date("2025-10-12T00:00:00.000Z"));
// 設(shè)置Header。
// meta.setHeader("yourHeader", "yourHeaderValue");
// 上傳文件。
ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content.getBytes()), meta);
// 驗(yàn)證URL訪問是否直接下載。
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("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
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("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}
相關(guān)文檔
如果您希望自定義OSS文件下載時(shí)的文件名,而不是以原Object名稱下載到本地,請參見自定義OSS文件下載時(shí)的文件名。
如果您希望通過瀏覽器使用自定義域名訪問OSS文件時(shí),直接預(yù)覽文件內(nèi)容,請參見如何配置訪問OSS文件時(shí)是預(yù)覽行為?。