Python使用预签名URL下载

更新时间:2025-04-03 01:51:41

默认情况下,OSS Bucket中的文件是私有的,仅文件拥有者可访问。本文介绍如何使用OSS Python SDK生成带有过期时间的GET方法预签名URL,以允许他人临时下载文件。在有效期内可多次访问,超期后需重新生成。

注意事项

  • 本文示例代码以华东1(杭州)的地域IDcn-hangzhou为例,默认使用外网Endpoint,如果您希望通过与OSS同地域的其他阿里云产品访问OSS,请使用内网Endpoint。关于OSS支持的RegionEndpoint的对应关系,请参见OSS地域和访问域名

  • 预签名URL无需权限即可生成,但仅当您拥有oss:GetObject权限时,第三方才能通过该预签名URL成功下载文件。具体授权操作,请参见RAM用户授权自定义的权限策略

  • 本文示例代码使用V4预签名URL,有效期最大为7天。更多信息,请参见签名版本4(推荐)

使用过程

使用预签名URL下载文件的过程如下:

image

方法定义

您可以使用预签名接口生成预签名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天。同时设置ExpirationExpires时,优先取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
    Java
    Node.js
    Python
    Go
    JavaScript
    Android-Java
    Objective-C
    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******************************************************"
    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();
        }
    }
    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);
    });
    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)
    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)
        }
    }
    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);
        });
    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();
            }
        }
    }
    #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
    
        #  # 设置自定义域名
        # cfg.endpoint = "http://ossv2.wangpeiyu.com"
        # # 设置使用CNAME
        # cfg.use_cname = True
    
        # 如果提供了自定义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
    Python
    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
    Python
    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()  # 脚本入口点,控制程序流程从这里开始

相关文档

  • 本页导读 (1)
  • 注意事项
  • 使用过程
  • 方法定义
  • 示例代码
  • 常见使用场景
  • 生成指定版本的文件的GET方法的预签名URL
  • 使用预签名URL下载指定请求头的文件
  • 使用预签名URL强制下载指定文件
  • 使用自定义域名生成用于下载的预签名URL
  • 相关文档
AI助理

点击开启售前

在线咨询服务

你好,我是AI助理

可以解答问题、推荐解决方案等