全部產品
Search
文件中心

Object Storage Service:如何配置通過自訂網域名訪問OSS檔案時實現強制下載?

更新時間:Jun 19, 2024

通過瀏覽器使用自訂網域名訪問OSS上儲存的檔案時,如果您的瀏覽器支援預覽所選的檔案格式,則OSS將直接預覽檔案內容。如果您希望通過瀏覽器使用自訂網域名訪問OSS檔案時,以附件形式下載檔案,您可以通過預簽名URL將response-content-disposition欄位設定為attachment來指定單次訪問為強制下載,還可以通過將檔案中繼資料Content-Disposition設定為attachment來指定所有訪問為強制下載。

通過預簽名URL設定單次訪問為強制下載

使用阿里雲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";
        // 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // 建立ClientBuilderConfiguration執行個體,您可以根據實際情況修改預設參數。
        ClientBuilderConfiguration conf = new ClientBuilderConfiguration();

        // 將CNAME取值設定為true,用於將自訂網域名綁定到目標Bucket。
        conf.setSupportCname(true);
        // 填寫Bucket名稱,例如examplebucket。
        String bucketName = "examplebucket";
        // 填寫Object完整路徑,例如exampleobject.txt。Object完整路徑中不能包含Bucket名稱。
        String objectName = "exampleobject.txt";        

        // 建立OSSClient執行個體。
        OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider, conf);

        try {
            // 建立請求。
            GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, objectName);
            // 設定HttpMethod為GET。
            generatePresignedUrlRequest.setMethod(HttpMethod.GET);
            // 設定簽名URL到期時間,單位為毫秒。本樣本以設定到期時間為1小時為例。
            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();
            }
        }
    }
}

通過檔案中繼資料設定所有訪問為強制下載

使用OSS控制台

  1. 登入OSS管理主控台

  2. 單擊Bucket 列表,然後單擊目標Bucket名稱。

  3. 在左側導覽列,選擇檔案管理 > 檔案清單

  4. 在目標Object右側選擇更多 > 設定檔案中繼資料

  5. 設定檔案中繼資料面板,將Content-Disposition設定為attachment,其他參數保留預設配置,然後單擊確定

  6. 在瀏覽器中通過自訂網域名以檔案URL的形式訪問目標檔案。

    • 以自訂網域名為example.com,Bucket根目錄下的檔案名稱為example.jpg為例(檔案讀寫權限為公用讀取或者公用讀寫),您可以在瀏覽器中通過自訂網域名拼接檔案URL的形式(http://example.com/example.jpg)訪問目標檔案。

    • 以自訂網域名為example.com,Bucket根目錄下的檔案名稱為example.jpg為例(檔案讀寫權限為私人),私人檔案URL需要添加簽名資訊(格式為http://example.com/example.jpg?簽名參數)。關於在瀏覽器中通過自訂網域名訪問私人檔案的具體操作,請參見使用自訂網域名訪問臨時檔案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";
        // 強烈建議不要把訪問憑證儲存到工程代碼裡,否則可能導致訪問憑證泄露,威脅您帳號下所有資源的安全。本程式碼範例以從環境變數中擷取訪問憑證為例。運行本程式碼範例之前,請先配置環境變數。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // 建立ClientBuilderConfiguration執行個體,您可以根據實際情況修改預設參數。
        ClientBuilderConfiguration conf = new ClientBuilderConfiguration();

        // 將CNAME取值設定為true,用於將自訂網域名綁定到目標Bucket。
        conf.setSupportCname(true);
        // 填寫Bucket名稱,例如examplebucket。
        String bucketName = "examplebucket";
        // 填寫不包含Bucket名稱在內的Object完整路徑,例如testfolder/exampleobject.txt。
        String objectName = "testfolder/exampleobject.txt";
        // 檔案內容。
        String content = "Hello OSS";

        // 建立OSSClient執行個體。
        OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider, conf);

        try {
            // 建立上傳檔案的中繼資料,可以通過檔案中繼資料設定HTTP標準屬性。
            ObjectMetadata meta = new ObjectMetadata();

            String md5 = BinaryUtil.toBase64String(BinaryUtil.calculateMd5(content.getBytes()));
            // 開啟檔案內容MD5校正。開啟後OSS會把您提供的MD5與檔案的MD5比較,不一致則拋出異常。
            meta.setContentMD5(md5);
            // 指定上傳的內容類型。內容類型決定瀏覽器將以什麼形式、什麼編碼讀取檔案。如果沒有指定則根據檔案的副檔名產生,如果沒有副檔名則為預設值application/octet-stream。
            meta.setContentType("text/plain");
            // 下載後顯示為原Object名稱。如果包含有中文字元,需要進行URL編碼。
            meta.setContentDisposition("attachment"+ URLEncoder.encode("UTF-8")+";"+URLEncoder.encode("UTF-8"));
            // 設定上傳檔案的長度。如超過此長度,則上傳檔案會被截斷,上傳的檔案長度為設定的長度。如小於此長度,則為上傳檔案的實際長度。
            // meta.setContentLength(content.length());
            // 設定內容被下載時網頁的緩衝行為。
            // meta.setCacheControl("Download Action");
            // 設定緩衝到期時間,格式是格林威治時間(GMT)。
            // meta.setExpirationTime(DateUtil.parseIso8601Date("2025-10-12T00:00:00.000Z"));

            // 設定Header。
            // meta.setHeader("yourHeader", "yourHeaderValue");

            // 上傳檔案。
            ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content.getBytes()), meta);

            // 驗證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();
            }
        }
    }
}

相關文檔