全部產品
Search
文件中心

Object Storage Service:使用預簽名URL下載(Python SDK V2)

更新時間:Jul 31, 2025

預設情況下,OSS Bucket中的檔案是私人的,僅檔案擁有者可訪問。本文介紹如何使用OSS Python SDK產生帶有到期時間的GET方法預簽名URL,以允許他人臨時下載檔案。在有效期間內可多次訪問,超期後需重建。

注意事項

  • 本文範例程式碼以華東1(杭州)的地區IDcn-hangzhou為例,預設使用外網Endpoint,如果您希望通過與OSS同地區的其他阿里雲產品訪問OSS,請使用內網Endpoint。關於OSS支援的Region與Endpoint的對應關係,請參見OSS地區和訪問網域名稱

  • 預簽名URL無需許可權即可產生,但僅當您擁有oss:GetObject許可權時,第三方才能通過該預簽名URL成功下載檔案。具體授權操作,請參見為RAM使用者授權自訂的權限原則

  • 本文範例程式碼使用V4預簽名URL,有效期間最大為7天。更多資訊,請參見簽名版本4(推薦)

使用過程

使用預簽名URL下載檔案的過程如下:

方法定義

您可以使用預簽名介面產生預簽名URL,授予對儲存空間中對象的限時存取權限。在到期時間之前,您可以多次使用預簽名URL。

預簽名URL方法定義如下:

presign(request: GetObjectRequest, **kwargs) → PresignResult

請求參數列表

參數名

類型

說明

request

GetObjectRequest

設定需要產生預簽名URL的方法名,具體請參見Client.presign

expires

datetime.timedelta

(選擇性參數)從目前時間開始,多長時間後預簽名URL到期。例如設定一個有效期間為30分鐘,30 * time.Minute。如果不指定,預設有效期間為15分鐘

expiration

datetime.datetime

(選擇性參數)指定一個具體的日期和時間,作為預簽名URL的有效截止時間

重要

在簽名版本V4下,有效期間最長為7天。同時設定Expiration和Expires時,優先取Expiration。

傳回值列表

類型

說明

PresignResult

返回結果,包含預簽名URL、HTTP方法、到期時間和參與簽名的要求標頭等,具體請參見PresignResult

其中,PresignResult傳回值列舉如下:

參數名

類型

說明

method

str

HTTP方法,和介面對應,例如GetObject介面,返回GET

url

str

預簽名URL

expiration

datetime

預簽名URL的到期時間

signed_headers

MutableMapping

被簽名的要求標頭,例如設定了content_type時,會返回 content_type的資訊

關於預簽名方法的完整定義,請參見presign

範例程式碼

  1. 檔案擁有者產生GET方法的預簽名URL。

    import argparse
    import alibabacloud_oss_v2 as oss
    
    # 建立一個命令列參數解析器,並描述指令碼用途:產生GET方法的預簽名URL請求樣本
    parser = argparse.ArgumentParser(description="presign get object sample")
    
    # 添加命令列參數 --region,表示儲存空間所在的地區,必需參數
    parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
    # 添加命令列參數 --bucket,表示要擷取對象的儲存空間名稱,必需參數
    parser.add_argument('--bucket', help='The name of the bucket.', required=True)
    # 添加命令列參數 --endpoint,表示其他服務可用來訪問OSS的網域名稱,非必需參數
    parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
    # 添加命令列參數 --key,表示對象(檔案)在OSS中的鍵名,必需參數
    parser.add_argument('--key', help='The name of the object.', required=True)
    
    def main():
        # 解析命令列提供的參數,擷取使用者輸入的值
        args = parser.parse_args()
    
        # 從環境變數中載入訪問OSS所需的認證資訊,用於身分識別驗證
        credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()
    
        # 使用SDK的預設配置建立設定物件,並設定認證提供者
        cfg = oss.config.load_default()
        cfg.credentials_provider = credentials_provider
        
        # 設定設定物件的地區屬性,根據使用者提供的命令列參數
        cfg.region = args.region
    
        # 如果提供了自訂endpoint,則更新設定物件中的endpoint屬性
        if args.endpoint is not None:
            cfg.endpoint = args.endpoint
    
        # 使用上述配置初始化OSS用戶端,準備與OSS互動
        client = oss.Client(cfg)
    
        # 產生預簽名的GET請求
        pre_result = client.presign(
            oss.GetObjectRequest(
                bucket=args.bucket,  # 指定儲存空間名稱
                key=args.key,        # 指定對象鍵名
            )
        )
    
        # 列印預簽章要求的方法、到期時間和URL
        print(f'method: {pre_result.method},'
              f' expiration: {pre_result.expiration.strftime("%Y-%m-%dT%H:%M:%S.000Z")},'
              f' url: {pre_result.url}'
        )
    
        # 列印預簽章要求的已簽名頭資訊
        for key, value in pre_result.signed_headers.items():
            print(f'signed headers key: {key}, signed headers value: {value}')
    
    # 當此指令碼被直接執行時,調用main函數開始處理邏輯
    if __name__ == "__main__":
        main()  # 指令碼進入點,控製程序流程從這裡開始
  2. 其他人使用GET方法的預簽名URL下載檔案。

    curl

    curl -SO "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************"

    Java

    import java.io.BufferedInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.net.HttpURLConnection;
    import java.net.URL;
    
    public class Demo {
        public static void main(String[] args) {
            // 替換為產生的GET方法的預簽名URL。
            String fileURL = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************";
            // 填寫檔案儲存的目標路徑,包括檔案名稱和副檔名。
            String savePath = "C:/downloads/myfile.txt";
    
            try {
                downloadFile(fileURL, savePath);
                System.out.println("Download completed!");
            } catch (IOException e) {
                System.err.println("Error during download: " + e.getMessage());
            }
        }
    
        private static void downloadFile(String fileURL, String savePath) throws IOException {
            URL url = new URL(fileURL);
            HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
            httpConn.setRequestMethod("GET");
    
            // 檢查響應代碼
            int responseCode = httpConn.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_OK) {
                // 輸入資料流
                InputStream inputStream = new BufferedInputStream(httpConn.getInputStream());
                // 輸出資料流
                FileOutputStream outputStream = new FileOutputStream(savePath);
    
                byte[] buffer = new byte[4096]; // 緩衝區
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
    
                outputStream.close();
                inputStream.close();
            } else {
                System.out.println("No file to download. Server replied HTTP code: " + responseCode);
            }
            httpConn.disconnect();
        }
    }

    Node.js

    const https = require('https');
    const fs = require('fs');
    
    const fileURL = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************";
    const savePath = "C:/downloads/myfile.txt";
    
    https.get(fileURL, (response) => {
        if (response.statusCode === 200) {
            const fileStream = fs.createWriteStream(savePath);
            response.pipe(fileStream);
            
            fileStream.on('finish', () => {
                fileStream.close();
                console.log("Download completed!");
            });
        } else {
            console.error(`Download failed. Server responded with code: ${response.statusCode}`);
        }
    }).on('error', (err) => {
        console.error("Error during download:", err.message);
    });

    Python

    import requests
    
    file_url = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************"
    save_path = "C:/downloads/myfile.txt"
    
    try:
        response = requests.get(file_url, stream=True)
        if response.status_code == 200:
            with open(save_path, 'wb') as f:
                for chunk in response.iter_content(4096):
                    f.write(chunk)
            print("Download completed!")
        else:
            print(f"No file to download. Server replied HTTP code: {response.status_code}")
    except Exception as e:
        print("Error during download:", e)

    Go

    package main
    
    import (
        "io"
        "net/http"
        "os"
    )
    
    func main() {
        fileURL := "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************"
        savePath := "C:/downloads/myfile.txt"
    
        response, err := http.Get(fileURL)
        if err != nil {
            panic(err)
        }
        defer response.Body.Close()
    
        if response.StatusCode == http.StatusOK {
            outFile, err := os.Create(savePath)
            if err != nil {
                panic(err)
            }
            defer outFile.Close()
    
            _, err = io.Copy(outFile, response.Body)
            if err != nil {
                panic(err)
            }
            println("Download completed!")
        } else {
            println("No file to download. Server replied HTTP code:", response.StatusCode)
        }
    }

    JavaScript

    const fileURL = "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************";
    const savePath = "C:/downloads/myfile.txt"; // 檔案將在下載時使用的檔案名稱
    
    fetch(fileURL)
        .then(response => {
            if (!response.ok) {
                throw new Error(`Server replied HTTP code: ${response.status}`);
            }
            return response.blob(); // 將響應轉換為 blob
        })
        .then(blob => {
            const link = document.createElement('a');
            link.href = window.URL.createObjectURL(blob);
            link.download = savePath; // 設定下載檔案的名字
            document.body.appendChild(link); // 此步驟確保連結存在於文檔中
            link.click(); // 類比點擊下載連結
            link.remove(); // 完成後移除連結
            console.log("Download completed!");
        })
        .catch(error => {
            console.error("Error during download:", error);
        });

    Android-Java

    import android.os.AsyncTask;
    import android.os.Environment;
    import java.io.BufferedInputStream;
    import java.io.FileOutputStream;
    import java.io.InputStream;
    import java.net.HttpURLConnection;
    import java.net.URL;
    
    public class DownloadTask extends AsyncTask<String, String, String> {
        @Override
        protected String doInBackground(String... params) {
            String fileURL = params[0];
            String savePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/myfile.txt"; // 修改後的儲存路徑
            try {
                URL url = new URL(fileURL);
                HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
                httpConn.setRequestMethod("GET");
                int responseCode = httpConn.getResponseCode();
                if (responseCode == HttpURLConnection.HTTP_OK) {
                    InputStream inputStream = new BufferedInputStream(httpConn.getInputStream());
                    FileOutputStream outputStream = new FileOutputStream(savePath);
                    byte[] buffer = new byte[4096];
                    int bytesRead;
                    while ((bytesRead = inputStream.read(buffer)) != -1) {
                        outputStream.write(buffer, 0, bytesRead);
                    }
                    outputStream.close();
                    inputStream.close();
                    return "Download completed!";
                } else {
                    return "No file to download. Server replied HTTP code: " + responseCode;
                }
            } catch (Exception e) {
                return "Error during download: " + e.getMessage();
            }
        }
    }

    Objective-C

    #import <Foundation/Foundation.h>
    
    int main(int argc, const char * argv[]) {
        @autoreleasepool {
            // 定義檔案 URL 和儲存路徑(修改為有效路徑)
            NSString *fileURL = @"https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241112T092756Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************/20241112/cn-hangzhou/oss/aliyun_v4_request&x-oss-signature=ed5a******************************************************";
            NSString *savePath = @"/Users/your_username/Desktop/myfile.txt"; // 請替換為您的使用者名稱
            
            // 建立 URL 對象
            NSURL *url = [NSURL URLWithString:fileURL];
            
            // 建立下載任務
            NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                // 錯誤處理
                if (error) {
                    NSLog(@"Error during download: %@", error.localizedDescription);
                    return;
                }
                
                // 檢查資料
                if (!data) {
                    NSLog(@"No data received.");
                    return;
                }
                
                // 儲存檔案
                NSError *writeError = nil;
                BOOL success = [data writeToURL:[NSURL fileURLWithPath:savePath] options:NSDataWritingAtomic error:&writeError];
                if (success) {
                    NSLog(@"Download completed!");
                } else {
                    NSLog(@"Error saving file: %@", writeError.localizedDescription);
                }
            }];
            
            // 啟動任務
            [task resume];
            
            // 讓主線程繼續運行以便非同步請求能夠完成
            [[NSRunLoop currentRunLoop] run];
        }
        return 0;
    }

常見使用情境

產生指定版本的檔案的GET方法的預簽名URL

以下程式碼範例在產生GET方法的預簽名URL時,指定了檔案的版本,以允許他人下載指定版本的檔案。

import argparse
import alibabacloud_oss_v2 as oss

# 建立一個命令列參數解析器,並描述指令碼用途:產生GET方法的預簽名URL請求樣本
parser = argparse.ArgumentParser(description="presign get object sample")

# 添加命令列參數 --region,表示儲存空間所在的地區,必需參數
parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
# 添加命令列參數 --bucket,表示要擷取對象的儲存空間名稱,必需參數
parser.add_argument('--bucket', help='The name of the bucket.', required=True)
# 添加命令列參數 --endpoint,表示其他服務可用來訪問OSS的網域名稱,非必需參數
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
# 添加命令列參數 --key,表示對象(檔案)在OSS中的鍵名,必需參數
parser.add_argument('--key', help='The name of the object.', required=True)

def main():
    # 解析命令列提供的參數,擷取使用者輸入的值
    args = parser.parse_args()

    # 從環境變數中載入訪問OSS所需的認證資訊,用於身分識別驗證
    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    # 使用SDK的預設配置建立設定物件,並設定認證提供者
    cfg = oss.config.load_default()
    cfg.credentials_provider = credentials_provider
    
    # 設定設定物件的地區屬性,根據使用者提供的命令列參數
    cfg.region = args.region

    # 如果提供了自訂endpoint,則更新設定物件中的endpoint屬性
    if args.endpoint is not None:
        cfg.endpoint = args.endpoint

    # 使用上述配置初始化OSS用戶端,準備與OSS互動
    client = oss.Client(cfg)

    # 產生預簽名的GET請求
    # 注意:version_id 參數是可選的,僅當您的儲存桶啟用了版本控制時才需要使用
    pre_result = client.presign(
        oss.GetObjectRequest(
            bucket=args.bucket,  # 指定儲存空間名稱
            key=args.key,        # 指定對象鍵名
            version_id='yourVersionId'  # 替換為實際的版本ID,如果適用
        )
    )

    # 列印預簽章要求的方法、到期時間和URL
    print(f'method: {pre_result.method},'
          f' expiration: {pre_result.expiration.strftime("%Y-%m-%dT%H:%M:%S.000Z")},'
          f' url: {pre_result.url}'
    )

    # 列印預簽章要求的已簽名頭資訊
    for key, value in pre_result.signed_headers.items():
        print(f'signed headers key: {key}, signed headers value: {value}')

# 當此指令碼被直接執行時,調用main函數開始處理邏輯
if __name__ == "__main__":
    main()  # 指令碼進入點,控製程序流程從這裡開始

使用預簽名URL下載指定要求標頭的檔案

在產生GET方式的預簽名URL時,如果指定了要求標頭,確保在通過該預簽名URL發起GET請求時也包含相應的要求標頭,以免出現不一致,導致請求失敗和預簽名錯誤。

  1. 產生帶要求標頭的GET方法預簽名URL。

    import argparse
    import alibabacloud_oss_v2 as oss
    
    # 建立一個命令列參數解析器,並描述指令碼用途:產生GET方法的預簽名URL請求樣本
    parser = argparse.ArgumentParser(description="presign get object sample")
    
    # 添加命令列參數 --region,表示儲存空間所在的地區,必需參數
    parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
    # 添加命令列參數 --bucket,表示要擷取對象的儲存空間名稱,必需參數
    parser.add_argument('--bucket', help='The name of the bucket.', required=True)
    # 添加命令列參數 --endpoint,表示其他服務可用來訪問OSS的網域名稱,非必需參數
    parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
    # 添加命令列參數 --key,表示對象(檔案)在OSS中的鍵名,必需參數
    parser.add_argument('--key', help='The name of the object.', required=True)
    
    def main():
        # 解析命令列提供的參數,擷取使用者輸入的值
        args = parser.parse_args()
    
        # 從環境變數中載入訪問OSS所需的認證資訊,用於身分識別驗證
        credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()
    
        # 使用SDK的預設配置建立設定物件,並設定認證提供者
        cfg = oss.config.load_default()
        cfg.credentials_provider = credentials_provider
    
        # 設定設定物件的地區屬性,根據使用者提供的命令列參數
        cfg.region = args.region
    
        # 如果提供了自訂endpoint,則更新設定物件中的endpoint屬性
        if args.endpoint is not None:
            cfg.endpoint = args.endpoint
    
        # 使用上述配置初始化OSS用戶端,準備與OSS互動
        client = oss.Client(cfg)
    
        # 產生預簽名的GET請求
        pre_result = client.presign(
            oss.GetObjectRequest(
                bucket=args.bucket,  # 指定儲存空間名稱
                key=args.key,        # 指定對象鍵名
                range_behavior="standard", # 指定要求標頭
                request_payer="requester", # 指定要求標頭
            )
        )
    
        # 列印預簽章要求的方法、到期時間和URL
        print(f'method: {pre_result.method},'
              f' expiration: {pre_result.expiration.strftime("%Y-%m-%dT%H:%M:%S.000Z")},'
              f' url: {pre_result.url}'
        )
    
        # 列印預簽章要求的已簽名頭資訊
        for key, value in pre_result.signed_headers.items():
            print(f'signed headers key: {key}, signed headers value: {value}')
    
    # 當此指令碼被直接執行時,調用main函數開始處理邏輯
    if __name__ == "__main__":
        main()  # 指令碼進入點,控製程序流程從這裡開始
  2. 使用預簽名URL並指定要求標頭下載檔案。

    curl -X GET "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-date=20241113T093321Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************&x-oss-signature=ed5a******************************************************" \
    -H "x-oss-range-behavior: standard" \
    -H "x-oss-request-payer: requester" \
    -o "myfile.txt"
    import requests
    
    def download_file(signed_url, file_path, headers=None, metadata=None):
        """
        使用預簽名的URL下載檔案。
    
        :param signed_url: 預簽名的URL。
        :param file_path: 要下載的檔案的完整路徑。
        :param headers: 可選,自訂HTTP頭部。
        :param metadata: 可選,自訂中繼資料(不會在GET請求中使用)。
        :return: None
        """
        if not headers:
            headers = {}
    
        try:
            response = requests.get(signed_url, headers=headers, stream=True)
            print(f"返回下載狀態代碼:{response.status_code}")
    
            if response.status_code == 200:
                with open(file_path, 'wb') as file:
                    for chunk in response.iter_content(chunk_size=8192):
                        if chunk:
                            file.write(chunk)
                print("檔案下載成功")
            else:
                print("下載失敗")
                print(response.text)
        except Exception as e:
            print(f"發生錯誤:{e}")
    
    if __name__ == "__main__":
        # 將<signedUrl>替換為授權URL。
        signed_url = "<signedUrl>"
        file_path = "/Users/yourLocalPath>/Downloads/downloadedFile.txt" # 儲存檔案的本地路徑
    
        headers = {
            "X-Oss-Range-Behavior":"standard",
            "X-Oss-Request-Payer":"requester",
        }
    
        download_file(signed_url, file_path, headers=headers)

使用預簽名URL強制下載指定檔案

  1. 產生帶response-content-disposition參數的簽名URL。

    import argparse
    import alibabacloud_oss_v2 as oss
    
    # 建立一個命令列參數解析器,並描述指令碼用途:產生GET方法的預簽名URL請求樣本
    parser = argparse.ArgumentParser(description="presign get object sample")
    
    # 添加命令列參數 --region,表示儲存空間所在的地區,必需參數
    parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
    # 添加命令列參數 --bucket,表示要擷取對象的儲存空間名稱,必需參數
    parser.add_argument('--bucket', help='The name of the bucket.', required=True)
    # 添加命令列參數 --endpoint,表示其他服務可用來訪問OSS的網域名稱,非必需參數
    parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
    # 添加命令列參數 --key,表示對象(檔案)在OSS中的鍵名,必需參數
    parser.add_argument('--key', help='The name of the object.', required=True)
    
    def main():
        # 解析命令列提供的參數,擷取使用者輸入的值
        args = parser.parse_args()
    
        # 從環境變數中載入訪問OSS所需的認證資訊,用於身分識別驗證
        credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()
    
        # 使用SDK的預設配置建立設定物件,並設定認證提供者
        cfg = oss.config.load_default()
        cfg.credentials_provider = credentials_provider
    
        # 設定設定物件的地區屬性,根據使用者提供的命令列參數
        cfg.region = args.region
    
        # 如果提供了自訂endpoint,則更新設定物件中的endpoint屬性
        if args.endpoint is not None:
            cfg.endpoint = args.endpoint
    
        # 使用上述配置初始化OSS用戶端,準備與OSS互動
        client = oss.Client(cfg)
    
        # 產生預簽名的GET請求
        pre_result = client.presign(
            oss.GetObjectRequest(
                bucket=args.bucket,  # 指定儲存空間名稱
                key=args.key,        # 指定對象鍵名
                response_content_disposition="attachment;filename=test.txt",
            )
        )
    
        # 列印預簽章要求的方法、到期時間和URL
        print(f'method: {pre_result.method},'
              f' expiration: {pre_result.expiration.strftime("%Y-%m-%dT%H:%M:%S.000Z")},'
              f' url: {pre_result.url}'
        )
    
        # 列印預簽章要求的已簽名頭資訊
        for key, value in pre_result.signed_headers.items():
            print(f'signed headers key: {key}, signed headers value: {value}')
    
    # 當此指令碼被直接執行時,調用main函數開始處理邏輯
    if __name__ == "__main__":
        main()  # 指令碼進入點,控製程序流程從這裡開始

  2. 直接使用帶query參數的簽名URL下載指定檔案。

    curl -X GET "https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?response-content-disposition=attachment%3B%20filename%3Dtest.txt&x-oss-date=20241113T093321Z&x-oss-expires=3599&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************&x-oss-signature=ed5a******************************************************" \
    -o "myfile.txt"
    import requests
    
    def download_file(signed_url, file_path):
        """
        使用預簽名的URL下載檔案。
    
        :param signed_url: 預簽名的URL。
        :param file_path: 要下載的檔案的完整路徑。
        :param headers: 可選,自訂HTTP頭部。
        :param metadata: 可選,自訂中繼資料(不會在GET請求中使用)。
        :return: None
        """
    
        try:
            response = requests.get(signed_url, stream=True)
            print(f"返回下載狀態代碼:{response.status_code}")
    
            if response.status_code == 200:
                with open(file_path, 'wb') as file:
                    for chunk in response.iter_content(chunk_size=8192):
                        if chunk:
                            file.write(chunk)
                print("檔案下載成功")
            else:
                print("下載失敗")
                print(response.text)
        except Exception as e:
            print(f"發生錯誤:{e}")
    
    if __name__ == "__main__":
        # 將<signedUrl>替換為授權URL。
        signed_url = "<signedUrl>"
        file_path = "/Users/yourLocalPath>/Downloads/downloadedFile.txt" # 儲存檔案的本地路徑
    
        download_file(signed_url, file_path)

使用自訂網域名產生用於下載的預簽名URL

以下程式碼範例在產生GET方法的預簽名URL時,使用了自訂網域名。

import argparse
import alibabacloud_oss_v2 as oss

# 建立一個命令列參數解析器,並描述指令碼用途:產生預簽名GET請求樣本
parser = argparse.ArgumentParser(description="presign get object sample")

# 添加命令列參數 --region,表示儲存空間所在的地區,必需參數
parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
# 添加命令列參數 --bucket,表示要擷取對象的儲存空間名稱,必需參數
parser.add_argument('--bucket', help='The name of the bucket.', required=True)
# 添加命令列參數 --endpoint,表示其他服務可用來訪問OSS的網域名稱,非必需參數
parser.add_argument('--endpoint', help='The domain names that other services can use to access OSS')
# 添加命令列參數 --key,表示對象(檔案)在OSS中的鍵名,必需參數
parser.add_argument('--key', help='The name of the object.', required=True)

def main():
    # 解析命令列提供的參數,擷取使用者輸入的值
    args = parser.parse_args()

    # 從環境變數中載入訪問OSS所需的認證資訊,用於身分識別驗證
    credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()

    # 使用SDK的預設配置建立設定物件,並設定認證提供者
    cfg = oss.config.load_default()
    cfg.credentials_provider = credentials_provider
    
    # 設定設定物件的地區屬性,根據使用者提供的命令列參數
    cfg.region = args.region

    # 設定自訂網域名,例如“http://static.example.com”
    cfg.endpoint = "http://static.example.com"
    
    # 設定使用CNAME
    cfg.use_cname = True

    # 使用上述配置初始化OSS用戶端,準備與OSS互動
    client = oss.Client(cfg)

    # 產生預簽名的GET請求
    pre_result = client.presign(
        oss.GetObjectRequest(
            bucket=args.bucket,  # 指定儲存空間名稱
            key=args.key,        # 指定對象鍵名
        )
    )

    # 列印預簽章要求的方法、到期時間和URL
    print(f'method: {pre_result.method},'
          f' expiration: {pre_result.expiration.strftime("%Y-%m-%dT%H:%M:%S.000Z")},'
          f' url: {pre_result.url}'
    )

    # 列印預簽章要求的已簽名頭資訊
    for key, value in pre_result.signed_headers.items():
        print(f'signed headers key: {key}, signed headers value: {value}')

# 當此指令碼被直接執行時,調用main函數開始處理邏輯
if __name__ == "__main__":
    main()  # 指令碼進入點,控製程序流程從這裡開始

相關文檔