OSS文件默认为私有权限,只有文件拥有者可访问。但文件拥有者可以生成分享链接(预签名URL),授权他人在有效期内下载或在线预览指定文件。
工作原理
预签名URL的生成过程依赖密钥加密和参数拼接,过程如下:
- 权限校验:您生成预签名URL时需拥有 - oss:GetObject权限,第三方才能通过该预签名URL成功下载/预览文件;
- 本地加密:基于AK/SK对文件路径、过期时间等信息加密计算,得到签名( - x-oss-signature);
- 附加签名:将签名参数( - x-oss-date、- x-oss-expires、- x-oss-credential等)作为查询字符串附加到文件URL;
- 形成链接:组成完整的预签名URL。 - 预签名URL格式 - https://BucketName.Endpoint/Object?签名参数- 完整示例 - https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-process=image%2Fresize%2Cp_10&x-oss-date=20241115T095058Z&x-oss-expires=3600&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************%2F20241115%2Fcn-hangzhou%2Foss%2Faliyun_v4_request&x-oss-signature=6e7a*********************************
详细生成过程请参见签名版本4(推荐)。
获取文件的下载链接
使用OSS默认访问域名生成文件的带有效期的下载链接(预签名URL)。
使用OSS控制台
您可以登录OSS管理控制台,进入目标Bucket的文件列表,单击目标文件后在右侧详情面板复制文件URL,即可获取默认有效期为32400秒(9小时)的临时下载链接。
使用阿里云SDK
以下是常见语言的生成文件的下载链接(预签名URL)的代码示例。
Java
更多示例,请参见Java使用预签名URL下载文件。
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import java.net.URL;
import java.util.Date;
public class Demo {
    public static void main(String[] args) throws Throwable {
        // 以华东1(杭州)的外网Endpoint为例,其它Region请按实际情况填写。
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // 填写Bucket名称,例如examplebucket。
        String bucketName = "examplebucket";
        // 填写Object完整路径,例如exampleobject.txt。Object完整路径中不能包含Bucket名称。
        String objectName = "exampleobject.txt";
        // 填写Bucket所在地域。以华东1(杭州)为例,Region填写为cn-hangzhou。
        String region = "cn-hangzhou";
        // 创建OSSClient实例。
        // 当OSSClient实例不再使用时,调用shutdown方法以释放资源。
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(credentialsProvider)
                .clientConfiguration(clientBuilderConfiguration)
                .region(region)
                .build();
        try {
            // 设置预签名URL过期时间,单位为毫秒。本示例以设置过期时间为1小时为例。
            Date expiration = new Date(new Date().getTime() + 3600 * 1000L);
            // 生成以GET方法访问的预签名URL。本示例没有额外请求头,其他人可以直接通过浏览器访问相关内容。
            URL url = ossClient.generatePresignedUrl(bucketName, objectName, expiration);
            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();
            }
        }
    }
}Python
更多示例,请参见Python使用预签名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()  # 脚本入口点,控制程序流程从这里开始Go
更多示例,请参见Go使用预签名URL下载文件。
package main
import (
	"context"
	"flag"
	"log"
	"time"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)
// 定义全局变量
var (
	region     string // 存储区域
	bucketName string // 存储空间名称
	objectName string // 对象名称
)
// init函数用于初始化命令行参数
func init() {
	flag.StringVar(®ion, "region", "", "The region in which the bucket is located.")
	flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
	flag.StringVar(&objectName, "object", "", "The name of the object.")
}
func main() {
	// 解析命令行参数
	flag.Parse()
	// 检查bucket名称是否为空
	if len(bucketName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, bucket name required")
	}
	// 检查region是否为空
	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}
	// 检查object名称是否为空
	if len(objectName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, object name required")
	}
	// 加载默认配置并设置凭证提供者和区域
	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region)
	// 创建OSS客户端
	client := oss.NewClient(cfg)
	// 生成GetObject的预签名URL
	result, err := client.Presign(context.TODO(), &oss.GetObjectRequest{
		Bucket: oss.Ptr(bucketName),
		Key:    oss.Ptr(objectName),
	},
		oss.PresignExpires(10*time.Minute),
	)
	if err != nil {
		log.Fatalf("failed to get object presign %v", err)
	}
	log.Printf("request method:%v\n", result.Method)
	log.Printf("request expiration:%v\n", result.Expiration)
	log.Printf("request url:%v\n", result.URL)
	if len(result.SignedHeaders) > 0 {
		//当返回结果包含签名头时,使用预签名URL发送GET请求时也包含相应的请求头,以免出现不一致,导致请求失败和预签名错误
		log.Printf("signed headers:\n")
		for k, v := range result.SignedHeaders {
			log.Printf("%v: %v\n", k, v)
		}
	}
}
Node.js
更多示例,请参见Node.js使用预签名URL下载文件。
const OSS = require("ali-oss");
// 定义一个生成预签名 URL 的函数
async function generateSignatureUrl(fileName) {
  // 获取预签名URL
  const client = await new OSS({
      // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
      accessKeyId: process.env.OSS_ACCESS_KEY_ID,
      accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
      bucket: 'examplebucket',
      // yourregion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
      region: 'oss-cn-hangzhou',
      // 设置secure为true,使用HTTPS,避免生成的下载链接被浏览器拦截
      secure: true,
      authorizationV4: true
  });
  return await client.signatureUrlV4('GET', 3600, {
      headers: {} // 请根据实际发送的请求头设置此处的请求头
  }, fileName);
}
// 调用函数并传入文件名
generateSignatureUrl('yourFileName').then(url => {
  console.log('Generated Signature URL:', url);
}).catch(err => {
  console.error('Error generating signature URL:', err);
});PHP
更多示例,请参见PHP使用预签名URL下载文件。
<?php
// 引入自动加载文件,确保依赖库能够正确加载
require_once __DIR__ . '/../vendor/autoload.php';
use AlibabaCloud\Oss\V2 as Oss;
// 定义命令行参数的描述信息
$optsdesc = [
    "region" => ['help' => 'The region in which the bucket is located.', 'required' => True], // Bucket所在的地域(必填)
    "endpoint" => ['help' => 'The domain names that other services can use to access OSS.', 'required' => False], // 访问域名(可选)
    "bucket" => ['help' => 'The name of the bucket', 'required' => True], // Bucket名称(必填)
    "key" => ['help' => 'The name of the object', 'required' => True], // 对象名称(必填)
];
// 将参数描述转换为getopt所需的长选项格式
// 每个参数后面加上":"表示该参数需要值
$longopts = \array_map(function ($key) {
    return "$key:";
}, array_keys($optsdesc));
// 解析命令行参数
$options = getopt("", $longopts);
// 验证必填参数是否存在
foreach ($optsdesc as $key => $value) {
    if ($value['required'] === True && empty($options[$key])) {
        $help = $value['help']; // 获取参数的帮助信息
        echo "Error: the following arguments are required: --$key, $help" . PHP_EOL;
        exit(1); // 如果必填参数缺失,则退出程序
    }
}
// 从解析的参数中提取值
$region = $options["region"]; // Bucket所在的地域
$bucket = $options["bucket"]; // Bucket名称
$key = $options["key"];       // 对象名称
// 加载环境变量中的凭证信息
// 使用EnvironmentVariableCredentialsProvider从环境变量中读取Access Key ID和Access Key Secret
$credentialsProvider = new Oss\Credentials\EnvironmentVariableCredentialsProvider();
// 使用SDK的默认配置
$cfg = Oss\Config::loadDefault();
$cfg->setCredentialsProvider($credentialsProvider); // 设置凭证提供者
$cfg->setRegion($region); // 设置Bucket所在的地域
if (isset($options["endpoint"])) {
    $cfg->setEndpoint($options["endpoint"]); // 如果提供了访问域名,则设置endpoint
}
// 创建OSS客户端实例
$client = new Oss\Client($cfg);
// 创建GetObjectRequest对象,用于下载对象
$request = new Oss\Models\GetObjectRequest(bucket:$bucket, key:$key);
// 调用presign方法生成预签名URL
$result = $client->presign($request);
// 打印预签名结果
// 输出预签名URL,用户可以直接使用该URL进行下载操作
print(
    'get object presign result:' . var_export($result, true) . PHP_EOL . // 预签名结果的详细信息
    'get object url:' . $result->url . PHP_EOL                           // 预签名URL,用于直接下载对象
);
.NET
更多示例,请参见.NET使用预签名URL下载文件。
using Aliyun.OSS;
using Aliyun.OSS.Common;
// 填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
var endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
var accessKeyId = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_ID");
var accessKeySecret = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET");
// 填写Bucket名称,例如examplebucket。
var bucketName = "examplebucket";
// 填写Object完整路径,完整路径中不包含Bucket名称,例如exampledir/exampleobject.txt。
var objectName = "exampledir/exampleobject.txt";
// 填写Bucket所在地域对应的Region。以华东1(杭州)为例,Region填写为cn-hangzhou。
const string region = "cn-hangzhou";
// 创建ClientConfiguration实例,按照您的需要修改默认参数。
var conf = new ClientConfiguration();
// 设置v4签名。
conf.SignatureVersion = SignatureVersion.V4;
// 创建OssClient实例。
var client = new OssClient(endpoint, accessKeyId, accessKeySecret, conf);
client.SetRegion(region);
try
{
    var metadata = client.GetObjectMetadata(bucketName, objectName);
    var etag = metadata.ETag;
    // 生成预签名URL。
    var req = new GeneratePresignedUriRequest(bucketName, objectName, SignHttpMethod.Get)
      {
        // 设置预签名URL过期时间,默认值为3600秒。
        Expiration = DateTime.UtcNow.AddHours(1),
    };
    var uri = client.GeneratePresignedUri(req);
    // 打印生成的预签名URL
    Console.WriteLine("Generated Signed URL: " + uri);
}
catch (OssException ex)
{
    Console.WriteLine("Failed with error code: {0}; Error info: {1}. \nRequestID:{2}\tHostID:{3}",
        ex.ErrorCode, ex.Message, ex.RequestId, ex.HostId);
}
catch (Exception ex)
{
    Console.WriteLine("Failed with error info: {0}", ex.Message);
}Android
更多SDK信息,请参见Android使用预签名URL下载文件。
// 填写Bucket名称,例如examplebucket。
String bucketName = "examplebucket";
// 填写不包含Bucket名称在内源Object的完整路径,例如exampleobject.txt。
String objectKey = "exampleobject.txt";
String url = null;
try {
    // 生成用于下载文件的预签名URL。
    GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, objectKey);
    // 设置预签名URL的过期时间为30分钟。
    request.setExpiration(30*60);
    request.setMethod(HttpMethod.GET);
    url = oss.presignConstrainedObjectURL(request);
    Log.d("url", url);
} catch (ClientException e) {
    e.printStackTrace();
}iOS
更多SDK信息,请参见iOS使用预签名URL下载文件。
// 填写Bucket名称。
NSString *bucketName = @"examplebucket";
// 填写Object名称。
NSString *objectKey = @"exampleobject.txt";
__block NSString *urlString;
// 生成用于下载的预签名URL,并指定预签名URL过期时间为30分钟。
OSSTask *task = [client presignConstrainURLWithBucketName:bucketName
                                            withObjectKey:objectKey
                                               httpMethod:@"GET"
                                   withExpirationInterval:30 * 60
                                           withParameters:@{}];
[task continueWithBlock:^id _Nullable(OSSTask * _Nonnull task) {
    if (task.error) {
        NSLog(@"presign error: %@", task.error);
    } else {
        urlString = task.result;
        NSLog(@"url: %@", urlString);
    }
    return nil;
}];C++
更多SDK信息,请参见C++使用预签名URL下载文件。
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;
int main(void)
{
    /* 初始化OSS账号信息。*/
            
    /* yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。*/
    std::string Endpoint = "yourEndpoint";
    /* yourRegion填写Bucket所在地域对应的Region。以华东1(杭州)为例,Region填写为cn-hangzhou。*/
    std::string Region = "yourRegion";
    /* 填写Bucket名称,例如examplebucket。*/
    std::string BucketName = "examplebucket";
    /* 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。*/ 
    std::string GetobjectUrlName = "exampledir/exampleobject.txt";
    /* 初始化网络等资源。*/
    InitializeSdk();
    ClientConfiguration conf;
    conf.signatureVersion = SignatureVersionType::V4;
    /* 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。*/
    auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
    OssClient client(Endpoint, credentialsProvider, conf);
    client.SetRegion(Region);
    /* 设置签名有效时长,最大有效时间为32400秒。*/
    std::time_t t = std::time(nullptr) + 1200;
    /* 生成预签名URL。*/
    auto genOutcome = client.GeneratePresignedUrl(BucketName, GetobjectUrlName, t, Http::Get);
    if (genOutcome.isSuccess()) {
        std::cout << "GeneratePresignedUrl success, Gen url:" << genOutcome.result().c_str() << std::endl;
    }
    else {
        /* 异常处理。*/
        std::cout << "GeneratePresignedUrl fail" <<
        ",code:" << genOutcome.error().Code() <<
        ",message:" << genOutcome.error().Message() <<
        ",requestId:" << genOutcome.error().RequestId() << std::endl;
        return -1;
    }
    /* 释放网络等资源。*/
    ShutdownSdk();
    return 0;
}Ruby
更多SDK信息,请参见Ruby使用预签名URL下载文件。
require 'aliyun/oss'
client = Aliyun::OSS::Client.new(
  # Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
  endpoint: 'https://oss-cn-hangzhou.aliyuncs.com',
  # 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
  access_key_id: ENV['OSS_ACCESS_KEY_ID'],
  access_key_secret: ENV['OSS_ACCESS_KEY_SECRET']
)
# 填写Bucket名称,例如examplebucket。
bucket = client.get_bucket('examplebucket')
# 生成预签名URL,并指定URL有效时间为1小时(3600秒)。
puts bucket.object_url('my-object', true, 3600)C
更多SDK信息,请参见C使用预签名URL下载文件。
#include "oss_api.h"
#include "aos_http_io.h"
/* yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。*/
const char *endpoint = "yourEndpoint";
/* 填写Bucket名称,例如examplebucket。*/
const char *bucket_name = "examplebucket";
/* 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。*/
const char *object_name = "exampledir/exampleobject.txt";
/* 填写本地文件的完整路径。*/
const char *local_filename = "yourLocalFilename";
void init_options(oss_request_options_t *options)
{
    options->config = oss_config_create(options->pool);
    /* 用char*类型的字符串初始化aos_string_t类型。*/
    aos_str_set(&options->config->endpoint, endpoint);
    /* 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。*/
    aos_str_set(&options->config->access_key_id, getenv("OSS_ACCESS_KEY_ID"));
    aos_str_set(&options->config->access_key_secret, getenv("OSS_ACCESS_KEY_SECRET"));
    /* 是否使用CNAME访问OSS服务。0表示不使用。*/
    options->config->is_cname = 0;
    /* 设置网络相关参数,例如超时时间等。*/
    options->ctl = aos_http_controller_create(options->pool, 0);
}
int main(int argc, char *argv[])
{
    /* 在程序入口调用aos_http_io_initialize方法来初始化网络、内存等全局资源。*/
    if (aos_http_io_initialize(NULL, 0) != AOSE_OK) {
        exit(1);
    }
    /* 用于内存管理的内存池(pool),等价于apr_pool_t。其实现代码在apr库中。*/
    aos_pool_t *pool;
    /* 重新创建一个内存池,第二个参数是NULL,表示没有继承其它内存池。*/
    aos_pool_create(&pool, NULL);
    /* 创建并初始化options,该参数包括endpoint、access_key_id、acces_key_secret、is_cname、curl等全局配置信息。*/
    oss_request_options_t *oss_client_options;
    /* 在内存池中分配内存给options。*/
    oss_client_options = oss_request_options_create(pool);
    /* 初始化Client的选项oss_client_options。*/
    init_options(oss_client_options);
    /* 初始化参数。*/
    aos_string_t bucket;
    aos_string_t object;
    aos_string_t file;    
    aos_http_request_t *req;
    apr_time_t now;
    char *url_str;
    aos_string_t url;
    int64_t expire_time; 
    int one_hour = 3600;
    aos_str_set(&bucket, bucket_name);
    aos_str_set(&object, object_name);
    aos_str_set(&file, local_filename);
    expire_time = now / 1000000 + one_hour;    
    req = aos_http_request_create(pool);
    req->method = HTTP_GET;
    now = apr_time_now();  
    /* 单位:微秒 */
    expire_time = now / 1000000 + one_hour;
    /* 生成预签名URL。*/
    url_str = oss_gen_signed_url(oss_client_options, &bucket, &object, expire_time, req);
    aos_str_set(&url, url_str);
    printf("临时下载URL: %s\n", url_str);     
    /* 释放内存池,相当于释放了请求过程中各资源分配的内存。*/
    aos_pool_destroy(pool);
    /* 释放之前分配的全局资源。*/
    aos_http_io_deinitialize();
    return 0;
}生成的预签名URL示例如下:
https://examplebucket.oss-cn-hangzhou.aliyuncs.com/exampleobject.txt?x-oss-process=image%2Fresize%2Cp_10&x-oss-date=20241115T095058Z&x-oss-expires=3600&x-oss-signature-version=OSS4-HMAC-SHA256&x-oss-credential=LTAI****************%2F20241115%2Fcn-hangzhou%2Foss%2Faliyun_v4_request&x-oss-signature=6e7a*********************************************使用命令行工具ossutil
对存储空间examplebucket里的example.txt对象,生成默认有效期为15分钟的文件的下载链接(预签名URL),命令如下。
ossutil presign oss://examplebucket/example.txt关于使用ossutil生成预签名URL的更多示例, 请参见presign(生成预签名URL)。
使用图形化管理工具ossbrowser
获取文件的在线预览链接
若要生成支持在线预览的链接(预签名 URL),需先绑定自定义域名。绑定完成后,使用自定义域名生成预签名URL。
使用OSS控制台
- 登录OSS管理控制台。 
- 单击Bucket列表,然后单击目标Bucket名称。 
- 在左侧导航栏,选择。 
- 在文件列表页面,单击目标文件名称。 
- 在详情面板的自有域名,选择绑定的自定义域名,其他保持默认值,然后单击复制文件URL。  
使用图形化管理工具ossbrowser
ossbrowser支持Object级别的操作与控制台支持的操作类似,请按照ossbrowser界面指引完成获取预签名URL的操作。如何下载ossbrowser,请参见图形化管理工具ossbrowser 2.0(预览版)。
- 使用自定义域名登录ossbrowser。  
- 获取文件URL。  
使用阿里云SDK
使用自定义域名新建OssClient并生成预签名URL。
Java
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.GeneratePresignedUrlRequest;
import java.net.URL;
import java.util.Date;
public class Demo {
    public static void main(String[] args) throws Throwable {
        // yourCustomEndpoint请填写您的自定义域名。例如http://static.example.com。
        String endpoint = "yourCustomEndpoint";
        // 请填写您存储空间所在的Region信息,例如cn-hangzhou
        String region = "cn-hangzhou";
        // 填写Bucket名称,例如examplebucket。
        String bucketName = "examplebucket";
        // 填写Object完整路径,例如exampleobject.txt。Object完整路径中不能包含Bucket名称。
        String objectName = "exampleobject.txt";
        // 从环境变量中获取访问凭证。运行本代码示例之前,请先配置环境变量
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // 创建OSSClient实例。
        // 当OSSClient实例不再使用时,调用shutdown方法以释放资源。
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        // 请注意,设置true开启CNAME选项
        clientBuilderConfiguration.setSupportCname(true);
        // 显式声明使用 V4 签名算法
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(credentialsProvider)
                .clientConfiguration(clientBuilderConfiguration)
                .region(region)
                .build();
        try {
            // 指定生成的预签名URL过期时间,单位为毫秒。本示例以设置过期时间为1小时为例。
            Date expiration = new Date(new Date().getTime() + 3600 * 1000L);
            // 生成预签名URL。
            GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, objectName, HttpMethod.GET);
            // 设置过期时间。
            request.setExpiration(expiration);
            // 通过HTTP GET请求生成预签名URL。
            URL signedUrl = ossClient.generatePresignedUrl(request);
            // 打印预签名URL。
            System.out.println("signed url for getObject: " + 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();
            }
        }
    }
}PHP
<?php
// 引入自动加载文件,确保依赖库能够正确加载
require_once __DIR__ . '/../vendor/autoload.php';
use AlibabaCloud\Oss\V2 as Oss;
// 定义命令行参数的描述信息
$optsdesc = [
    "region" => ['help' => 'The region in which the bucket is located.', 'required' => True], // Bucket所在的地域(必填)
    "endpoint" => ['help' => 'The domain names that other services can use to access OSS.', 'required' => False], // 访问域名(可选)
    "bucket" => ['help' => 'The name of the bucket', 'required' => True], // Bucket名称(必填)
    "key" => ['help' => 'The name of the object', 'required' => True], // 对象名称(必填)
];
// 将参数描述转换为getopt所需的长选项格式
// 每个参数后面加上":"表示该参数需要值
$longopts = \array_map(function ($key) {
    return "$key:";
}, array_keys($optsdesc));
// 解析命令行参数
$options = getopt("", $longopts);
// 验证必填参数是否存在
foreach ($optsdesc as $key => $value) {
    if ($value['required'] === True && empty($options[$key])) {
        $help = $value['help']; // 获取参数的帮助信息
        echo "Error: the following arguments are required: --$key, $help" . PHP_EOL;
        exit(1); // 如果必填参数缺失,则退出程序
    }
}
// 从解析的参数中提取值
$region = $options["region"]; // Bucket所在的地域
$bucket = $options["bucket"]; // Bucket名称
$key = $options["key"];       // 对象名称
// 加载环境变量中的凭证信息
// 使用EnvironmentVariableCredentialsProvider从环境变量中读取Access Key ID和Access Key Secret
$credentialsProvider = new Oss\Credentials\EnvironmentVariableCredentialsProvider();
// 使用SDK的默认配置
$cfg = Oss\Config::loadDefault();
$cfg->setCredentialsProvider($credentialsProvider); // 设置凭证提供者
$cfg->setRegion($region); // 设置Bucket所在的地域
$cfg->setEndpoint(endpoint: "http://static.example.com"); // 请设置为您的自定义endpoint
$cfg->setUseCname(true); // 设置为使用CNAME
// 创建OSS客户端实例
$client = new Oss\Client($cfg);
// 创建GetObjectRequest对象,用于下载对象
$request = new Oss\Models\GetObjectRequest(bucket:$bucket, key:$key);
// 调用presign方法生成预签名URL
$result = $client->presign($request);
// 打印预签名结果
// 输出预签名URL,用户可以直接使用该URL进行下载操作
print(
    'get object presign result:' . var_export($result, true) . PHP_EOL . // 预签名结果的详细信息
    'get object url:' . $result->url . PHP_EOL                           // 预签名URL,用于直接下载对象
);
Node.js
const OSS = require("ali-oss");
// 定义一个生成预签名 URL 的函数
async function generateSignatureUrl(fileName) {
  // 获取预签名URL
  const client = await new OSS({
      // 使用自定义域名作为Endpoint。
      endpoint: 'http://static.example.com', 
      // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
      accessKeyId: process.env.OSS_ACCESS_KEY_ID,
      accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
      bucket: 'examplebucket',
      // yourregion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
      region: 'oss-cn-hangzhou',
      authorizationV4: true,
      cname: true
  });
  return await client.signatureUrlV4('GET', 3600, {
      headers: {} // 请根据实际发送的请求头设置此处的请求头
  }, fileName);
}
// 调用函数并传入文件名
generateSignatureUrl('yourFileName').then(url => {
  console.log('Generated Signature URL:', url);
}).catch(err => {
  console.error('Error generating signature URL:', err);
});Python
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()  # 脚本入口点,控制程序流程从这里开始Go
package main
import (
	"context"
	"flag"
	"log"
	"time"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)
// 定义全局变量
var (
	region     string // 存储区域
	bucketName string // 存储空间名称
	objectName string // 对象名称
)
// init函数用于初始化命令行参数
func init() {
	flag.StringVar(®ion, "region", "", "The region in which the bucket is located.")
	flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
	flag.StringVar(&objectName, "object", "", "The name of the object.")
}
func main() {
	// 解析命令行参数
	flag.Parse()
	// 检查bucket名称是否为空
	if len(bucketName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, bucket name required")
	}
	// 检查region是否为空
	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}
	// 检查object名称是否为空
	if len(objectName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, object name required")
	}
	// 加载默认配置并设置凭证提供者和区域
	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region).
		WithEndpoint("http://static.example.com").
		WithUseCName(true)
	// 创建OSS客户端
	client := oss.NewClient(cfg)
	// 生成GetObject的预签名URL
	result, err := client.Presign(context.TODO(), &oss.GetObjectRequest{
		Bucket: oss.Ptr(bucketName),
		Key:    oss.Ptr(objectName),
		//RequestPayer: oss.Ptr("requester"), // 指定请求者身份
	},
		oss.PresignExpires(10*time.Minute),
	)
	if err != nil {
		log.Fatalf("failed to get object presign %v", err)
	}
	log.Printf("request method:%v\n", result.Method)
	log.Printf("request expiration:%v\n", result.Expiration)
	log.Printf("request url:%v\n", result.URL)
	if len(result.SignedHeaders) > 0 {
		//当返回结果包含预签名头时,使用预签名URL发送GET请求时也包含相应的请求头,以免出现不一致,导致请求失败和预签名错误
		log.Printf("signed headers:\n")
		for k, v := range result.SignedHeaders {
			log.Printf("%v: %v\n", k, v)
		}
	}
}使用命令行工具ossutil
使用自定义域名通过presign(生成预预签名URL)命令生成文件的预签名URL。
ossutil presign oss://examplebucket/exampleobject.txt --endpoint "http://static.example.com” --addressing-style "cname"如需ossutil命令自动使用自定义域名,而无需每次在命令中手动指定自定义域名,您可以在配置文件中添加自定义域名,
如果链接仍无法预览,还需检查以下配置。
- 是否为Office 文件? - 当前方法不支持在浏览器中预览Word、Excel、PPT 等Office文件,如需预览Office文件,请使用WebOffice在线预览功能。 
- Content-Type设置是否合理?- 如果文件的 - Content-Type与实际类型不一致,浏览器可能无法正确识别并渲染内容,从而将文件作为附件下载。您可以对照如何设置Content-Type(MIME)?确认文件扩展名与- Content-Type是否匹配。如不一致,请参考管理文件元数据中的方法修改文件的- Content-Type。
- Content-Disposition是否为- inline?- 如果文件的 - Content-Disposition被设置为- attachment,浏览器会强制下载文件。请参考管理文件元数据中的方法其修改为- inline以支持预览。
- 是否刷新CDN缓存? - 如果您未使用CDN加速,可忽略本项。 - 如果您使用CDN访问OSS资源,修改文件元数据后需刷新 CDN 缓存,否则仍可能读取旧配置,导致预览不生效。 
获取文件的强制下载链接
如果当前链接(预签名URL)在浏览器中打开会直接预览,但您希望改为下载效果,可使用以下方法。方式一优先级高于方式二。
方式一:单次强制下载
仅对当前生成的链接生效。通过在生成 URL 时设置response-content-disposition参数为attachment实现。
Java
导入GeneratePresignedUrlRequest类。
import com.aliyun.oss.model.GeneratePresignedUrlRequest;使用 GeneratePresignedUrlRequest方法,并设置response-content-disposition响应头为attachment。
// 构建 GET 请求的预签名 URL
GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(
    bucketName, objectName, HttpMethod.GET);
// 设置强制下载
request.getResponseHeaders().setContentDisposition("attachment");Python
在GetObjectRequest中添加response_content_disposition参数,并设置值为attachment。
    # 生成预签名的GET请求
    pre_result = client.presign(
        oss.GetObjectRequest(
            bucket=args.bucket,  # 指定存储空间名称
            key=args.key,        # 指定对象键名
            response_content_disposition="attachment",# 设置为强制下载
        )
    )Go
在GetObjectRequest中添加ResponseContentDisposition参数,并设置值为attachment。
// 生成带有强制下载行为的预签名 GET 请求
result, err := client.Presign(context.TODO(), &oss.GetObjectRequest{
    Bucket:                     oss.Ptr(bucketName),
    Key:                        oss.Ptr(objectName),
    ResponseContentDisposition: oss.Ptr("attachment"), // 设置为强制下载
})方式二:统一设置强制下载(通过元数据)
一次设置后,该文件的所有访问都会强制下载。通过修改文件元数据中的Content-Disposition字段实现。
使用OSS控制台
在OSS管理控制台中,找到目标文件,在该文件详情面板中单击设置文件元数据,将Content-Disposition设置为attachment,然后单击确定保存。
除控制台操作外,也可参考管理文件元数据,通过SDK或命令行工具 ossutil 设置该字段。
如您还希望自定义下载时显示的文件名,请参见自定义下载时的文件名。
获取指定版本文件的链接
生成指定版本文件的链接(预签名URL),适用于已启用版本控制的Bucket。
使用OSS控制台
- 您可以登录OSS管理控制台,进入目标Bucket的文件列表,在页面右上角切换历史版本为显示。  
- 找到目标文件,单击所需历史版本的文件名,在详情页面中即可复制该版本文件的URL。  
使用阿里云SDK
Java
增加以下关键代码:
// 1. 定义版本ID变量
String versionId = "CAEQARiBgID8rumR2hYiIGUyOTAyZGY2MzU5MjQ5ZjlhYzQzZjNlYTAyZDE3****";
// 2. 创建查询参数Map
Map<String, String> queryParam = new HashMap<String, String>();
queryParam.put("versionId", versionId);
// 3. 将版本ID参数添加到请求中
request.setQueryParameter(queryParam);Python
在GetObjectRequest中添加version_id参数。
pre_result = client.presign(
    oss.GetObjectRequest(
        bucket=bucket_name,
        key=object_name,
        version_id='CAEQARiBgID8rumR2hYiIGUyOTAyZGY2MzU5MjQ5ZjlhYzQzZjNlYTAyZDE3****'  # 设置VersionId参数 
    )
)Go
在GetObjectRequest中添加VersionId字段。
result, err := client.Presign(context.TODO(), &oss.GetObjectRequest{
    Bucket:    oss.Ptr(bucketName),
    Key:       oss.Ptr(objectName),
    VersionId: oss.Ptr("CAEQARiBgID8rumR2hYiIGUyOTAyZGY2MzU5MjQ5ZjlhYzQzZjNlYTAyZDE7****"), // 设置VersionId
}, oss.PresignExpires(10*time.Minute))Node.js
在signatureUrlV4中添加queries参数。
const signedUrl = await client.signatureUrlV4('GET', 3600, {
  queries: {
    "versionId": 'CAEQARiBgID8rumR2hYiIGUyOTAyZGY2MzU5MjQ5ZjlhYzQzZjNlYTAyZDE7****'  // 新增versionId参数
  }
}, objectName);PHP
在GetObjectRequest中添加versionId参数。
// 新增指定版本参数
$versionId = "yourVersionId"; // 替换为实际版本号
$request = new Oss\Models\GetObjectRequest(bucket:$bucket, key:$key, versionId:$versionId);使用ossutil
对存储空间examplebucket里的example.txt对象,生成版本标识为123的预签名URL。
ossutil presign oss://examplebucket/example.txt --version-id 123批量获取文件的链接
推荐使用命令行工具ossutil,可为整个目录下的文件批量生成链接。
使用命令行工具ossutil
- 对存储空间examplebucke内folder目录下所有文件,批量生成默认有效期为15分钟的预签名URL。 - ossutil presign oss://examplebucket/folder/ -r
- 对存储空间examplebucket里的folder目录下的后缀为.txt的文件,批量生成默认有效期为15分钟的预签名URL。 - ossutil presign oss://examplebucket/folder/ -r --include "*.txt"
- 对存储空间examplebucket下所有文件,批量生成默认有效期为15分钟的预签名URL。 - ossutil presign oss://examplebucket/ -r
关于使用ossutil生成预签名URL的更多用法, 请参见presign(生成预签名URL)。
使用OSS控制台
仅支持导出当前目录下文件的预签名URL,无法导出子目录中的文件的预签名URL。
- 选中目标文件,然后单击下方的导出URL列表。  
- 在弹出的配置面板中,默认参数适用于大多数场景,无需修改即可使用。 
- 单击确定,下载并保存生成的URL列表文件。 
使用阿里云SDK
使用GetBucket (ListObjects)接口获取所有Object名称,然后逐个生成预签名URL。
自定义下载文件名
在强制下载的基础上,您可以进一步指定用户保存文件时看到的文件名。方式一优先级高于方式二。
方式一:单次设置下载文件名
为单个预签名URL指定下载文件名。只需在设置response-content-disposition参数为attachment的基础上增加filename参数。
Java
设置response-content-disposition参数。
// 设置客户端下载时显示的文件名,此处以 "test.txt" 为例
String filename = "test.txt";
request.getResponseHeaders().setContentDisposition("attachment;filename=" + URLEncoder.encode(filename,"UTF-8"));Python
通过response_content_disposition参数,实现自定义下载文件名为test.txt。
    # 生成预签名的GET请求
    pre_result = client.presign(
        oss.GetObjectRequest(
            bucket=args.bucket,  # 指定存储空间名称
            key=args.key,        # 指定对象键名
            response_content_disposition="attachment;filename=test.txt",# 设置客户端下载时显示的文件名,此处为 "test.txt"
        )
    )Go
通过ResponseContentDisposition参数,实现自定义下载文件名为test.txt。
// 生成带有强制下载行为的预签名 GET 请求
result, err := client.Presign(context.TODO(), &oss.GetObjectRequest{
    Bucket:                     oss.Ptr(bucketName),
    Key:                        oss.Ptr(objectName),
    ResponseContentDisposition: oss.Ptr("attachment;filename=test.txt"),//设置客户端下载时显示的文件名,此处为 "test.txt"
})方式二:统一设置(通过元数据)
修改元数据,为所有访问设置一个统一的默认下载名。通过修改文件元数据中的Content-Disposition字段为attachment; filename="yourFileName"实现,yourFileName为自定义的文件名称,例如example.jpg。
设置链接的有效时间
链接(预签名URL)的有效期在生成时设定,过后无法修改。链接在有效期内可多次访问,过期后失效。
不同生成方式支持的最大有效期不同,超出上限会导致生成失败或访问异常。
使用OSS控制台
您可以登录OSS管理控制台,进入目标Bucket的文件列表,单击目标文件后在右侧详情面板过期时间,设置链接有效期。
使用阿里云SDK
您需拥有oss:GetObject权限,第三方才能通过该预签名URL成功下载文件。具体授权操作,请参见为RAM用户授权自定义的权限策略。生成后,您可将链接发送给需要访问该文件的第三方。
通过修改代码中的expiration来设置预签名URL的过期时间。
Java
更多SDK信息,请参见Java使用预签名URL下载文件。
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import java.net.URL;
import java.util.Date;
public class Demo {
    public static void main(String[] args) throws Throwable {
        // 以华东1(杭州)的外网Endpoint为例,其它Region请按实际情况填写。
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // 填写Bucket名称,例如examplebucket。
        String bucketName = "examplebucket";
        // 填写Object完整路径,例如exampleobject.txt。Object完整路径中不能包含Bucket名称。
        String objectName = "exampleobject.txt";
        // 填写Bucket所在地域。以华东1(杭州)为例,Region填写为cn-hangzhou。
        String region = "cn-hangzhou";
        // 创建OSSClient实例。
        // 当OSSClient实例不再使用时,调用shutdown方法以释放资源。
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
        OSS ossClient = OSSClientBuilder.create()
                .endpoint(endpoint)
                .credentialsProvider(credentialsProvider)
                .clientConfiguration(clientBuilderConfiguration)
                .region(region)
                .build();
        try {
            // 设置预签名URL过期时间,单位为毫秒。本示例以设置过期时间为1小时为例。
            Date expiration = new Date(new Date().getTime() + 3600 * 1000L);
            // 生成以GET方法访问的预签名URL。本示例没有额外请求头,其他人可以直接通过浏览器访问相关内容。
            URL url = ossClient.generatePresignedUrl(bucketName, objectName, expiration);
            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();
            }
        }
    }
}Python
更多SDK信息,请参见Python使用预签名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()  # 脚本入口点,控制程序流程从这里开始Go
更多SDK信息,请参见Go使用预签名URL下载文件。
package main
import (
	"context"
	"flag"
	"log"
	"time"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
	"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)
// 定义全局变量
var (
	region     string // 存储区域
	bucketName string // 存储空间名称
	objectName string // 对象名称
)
// init函数用于初始化命令行参数
func init() {
	flag.StringVar(®ion, "region", "", "The region in which the bucket is located.")
	flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
	flag.StringVar(&objectName, "object", "", "The name of the object.")
}
func main() {
	// 解析命令行参数
	flag.Parse()
	// 检查bucket名称是否为空
	if len(bucketName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, bucket name required")
	}
	// 检查region是否为空
	if len(region) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, region required")
	}
	// 检查object名称是否为空
	if len(objectName) == 0 {
		flag.PrintDefaults()
		log.Fatalf("invalid parameters, object name required")
	}
	// 加载默认配置并设置凭证提供者和区域
	cfg := oss.LoadDefaultConfig().
		WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
		WithRegion(region)
	// 创建OSS客户端
	client := oss.NewClient(cfg)
	// 生成GetObject的预签名URL
	result, err := client.Presign(context.TODO(), &oss.GetObjectRequest{
		Bucket: oss.Ptr(bucketName),
		Key:    oss.Ptr(objectName),
	},
		oss.PresignExpires(10*time.Minute),
	)
	if err != nil {
		log.Fatalf("failed to get object presign %v", err)
	}
	log.Printf("request method:%v\n", result.Method)
	log.Printf("request expiration:%v\n", result.Expiration)
	log.Printf("request url:%v\n", result.URL)
	if len(result.SignedHeaders) > 0 {
		//当返回结果包含签名头时,使用预签名URL发送GET请求时也包含相应的请求头,以免出现不一致,导致请求失败和预签名错误
		log.Printf("signed headers:\n")
		for k, v := range result.SignedHeaders {
			log.Printf("%v: %v\n", k, v)
		}
	}
}
Node.js
更多SDK信息,请参见Node.js使用预签名URL下载文件。
const OSS = require("ali-oss");
// 定义一个生成预签名 URL 的函数
async function generateSignatureUrl(fileName) {
  // 获取预签名URL
  const client = await new OSS({
      // 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
      accessKeyId: process.env.OSS_ACCESS_KEY_ID,
      accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
      bucket: 'examplebucket',
      // yourregion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
      region: 'oss-cn-hangzhou',
      // 设置secure为true,使用HTTPS,避免生成的下载链接被浏览器拦截
      secure: true,
      authorizationV4: true
  });
  return await client.signatureUrlV4('GET', 3600, {
      headers: {} // 请根据实际发送的请求头设置此处的请求头
  }, fileName);
}
// 调用函数并传入文件名
generateSignatureUrl('yourFileName').then(url => {
  console.log('Generated Signature URL:', url);
}).catch(err => {
  console.error('Error generating signature URL:', err);
});PHP
更多SDK信息,请参见PHP使用预签名URL下载文件。
<?php
// 引入自动加载文件,确保依赖库能够正确加载
require_once __DIR__ . '/../vendor/autoload.php';
use AlibabaCloud\Oss\V2 as Oss;
// 定义命令行参数的描述信息
$optsdesc = [
    "region" => ['help' => 'The region in which the bucket is located.', 'required' => True], // Bucket所在的地域(必填)
    "endpoint" => ['help' => 'The domain names that other services can use to access OSS.', 'required' => False], // 访问域名(可选)
    "bucket" => ['help' => 'The name of the bucket', 'required' => True], // Bucket名称(必填)
    "key" => ['help' => 'The name of the object', 'required' => True], // 对象名称(必填)
];
// 将参数描述转换为getopt所需的长选项格式
// 每个参数后面加上":"表示该参数需要值
$longopts = \array_map(function ($key) {
    return "$key:";
}, array_keys($optsdesc));
// 解析命令行参数
$options = getopt("", $longopts);
// 验证必填参数是否存在
foreach ($optsdesc as $key => $value) {
    if ($value['required'] === True && empty($options[$key])) {
        $help = $value['help']; // 获取参数的帮助信息
        echo "Error: the following arguments are required: --$key, $help" . PHP_EOL;
        exit(1); // 如果必填参数缺失,则退出程序
    }
}
// 从解析的参数中提取值
$region = $options["region"]; // Bucket所在的地域
$bucket = $options["bucket"]; // Bucket名称
$key = $options["key"];       // 对象名称
// 加载环境变量中的凭证信息
// 使用EnvironmentVariableCredentialsProvider从环境变量中读取Access Key ID和Access Key Secret
$credentialsProvider = new Oss\Credentials\EnvironmentVariableCredentialsProvider();
// 使用SDK的默认配置
$cfg = Oss\Config::loadDefault();
$cfg->setCredentialsProvider($credentialsProvider); // 设置凭证提供者
$cfg->setRegion($region); // 设置Bucket所在的地域
if (isset($options["endpoint"])) {
    $cfg->setEndpoint($options["endpoint"]); // 如果提供了访问域名,则设置endpoint
}
// 创建OSS客户端实例
$client = new Oss\Client($cfg);
// 创建GetObjectRequest对象,用于下载对象
$request = new Oss\Models\GetObjectRequest(bucket:$bucket, key:$key);
// 调用presign方法生成预签名URL
$result = $client->presign($request);
// 打印预签名结果
// 输出预签名URL,用户可以直接使用该URL进行下载操作
print(
    'get object presign result:' . var_export($result, true) . PHP_EOL . // 预签名结果的详细信息
    'get object url:' . $result->url . PHP_EOL                           // 预签名URL,用于直接下载对象
);
.NET
更多SDK信息,请参见.NET使用预签名URL下载文件。
using Aliyun.OSS;
using Aliyun.OSS.Common;
// 填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
var endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
var accessKeyId = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_ID");
var accessKeySecret = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET");
// 填写Bucket名称,例如examplebucket。
var bucketName = "examplebucket";
// 填写Object完整路径,完整路径中不包含Bucket名称,例如exampledir/exampleobject.txt。
var objectName = "exampledir/exampleobject.txt";
// 填写Bucket所在地域对应的Region。以华东1(杭州)为例,Region填写为cn-hangzhou。
const string region = "cn-hangzhou";
// 创建ClientConfiguration实例,按照您的需要修改默认参数。
var conf = new ClientConfiguration();
// 设置v4签名。
conf.SignatureVersion = SignatureVersion.V4;
// 创建OssClient实例。
var client = new OssClient(endpoint, accessKeyId, accessKeySecret, conf);
client.SetRegion(region);
try
{
    var metadata = client.GetObjectMetadata(bucketName, objectName);
    var etag = metadata.ETag;
    // 生成预签名URL。
    var req = new GeneratePresignedUriRequest(bucketName, objectName, SignHttpMethod.Get)
      {
        // 设置预签名URL过期时间,默认值为3600秒。
        Expiration = DateTime.UtcNow.AddHours(1),
    };
    var uri = client.GeneratePresignedUri(req);
    // 打印生成的预签名URL
    Console.WriteLine("Generated Signed URL: " + uri);
}
catch (OssException ex)
{
    Console.WriteLine("Failed with error code: {0}; Error info: {1}. \nRequestID:{2}\tHostID:{3}",
        ex.ErrorCode, ex.Message, ex.RequestId, ex.HostId);
}
catch (Exception ex)
{
    Console.WriteLine("Failed with error info: {0}", ex.Message);
}Android
更多SDK信息,请参见Android使用预签名URL下载文件。
// 填写Bucket名称,例如examplebucket。
String bucketName = "examplebucket";
// 填写不包含Bucket名称在内源Object的完整路径,例如exampleobject.txt。
String objectKey = "exampleobject.txt";
String url = null;
try {
    // 生成用于下载文件的预签名URL。
    GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, objectKey);
    // 设置预签名URL的过期时间为30分钟。
    request.setExpiration(30*60);
    request.setMethod(HttpMethod.GET);
    url = oss.presignConstrainedObjectURL(request);
    Log.d("url", url);
} catch (ClientException e) {
    e.printStackTrace();
}iOS
更多SDK信息,请参见iOS使用预签名URL下载文件。
// 填写Bucket名称。
NSString *bucketName = @"examplebucket";
// 填写Object名称。
NSString *objectKey = @"exampleobject.txt";
__block NSString *urlString;
// 生成用于下载的预签名URL,并指定预签名URL过期时间为30分钟。
OSSTask *task = [client presignConstrainURLWithBucketName:bucketName
                                            withObjectKey:objectKey
                                               httpMethod:@"GET"
                                   withExpirationInterval:30 * 60
                                           withParameters:@{}];
[task continueWithBlock:^id _Nullable(OSSTask * _Nonnull task) {
    if (task.error) {
        NSLog(@"presign error: %@", task.error);
    } else {
        urlString = task.result;
        NSLog(@"url: %@", urlString);
    }
    return nil;
}];C++
更多SDK信息,请参见C++使用预签名URL下载文件。
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;
int main(void)
{
    /* 初始化OSS账号信息。*/
            
    /* yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。*/
    std::string Endpoint = "yourEndpoint";
    /* yourRegion填写Bucket所在地域对应的Region。以华东1(杭州)为例,Region填写为cn-hangzhou。*/
    std::string Region = "yourRegion";
    /* 填写Bucket名称,例如examplebucket。*/
    std::string BucketName = "examplebucket";
    /* 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。*/ 
    std::string GetobjectUrlName = "exampledir/exampleobject.txt";
    /* 初始化网络等资源。*/
    InitializeSdk();
    ClientConfiguration conf;
    conf.signatureVersion = SignatureVersionType::V4;
    /* 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。*/
    auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
    OssClient client(Endpoint, credentialsProvider, conf);
    client.SetRegion(Region);
    /* 设置签名有效时长,最大有效时间为32400秒。*/
    std::time_t t = std::time(nullptr) + 1200;
    /* 生成预签名URL。*/
    auto genOutcome = client.GeneratePresignedUrl(BucketName, GetobjectUrlName, t, Http::Get);
    if (genOutcome.isSuccess()) {
        std::cout << "GeneratePresignedUrl success, Gen url:" << genOutcome.result().c_str() << std::endl;
    }
    else {
        /* 异常处理。*/
        std::cout << "GeneratePresignedUrl fail" <<
        ",code:" << genOutcome.error().Code() <<
        ",message:" << genOutcome.error().Message() <<
        ",requestId:" << genOutcome.error().RequestId() << std::endl;
        return -1;
    }
    /* 释放网络等资源。*/
    ShutdownSdk();
    return 0;
}Ruby
更多SDK信息,请参见Ruby使用预签名URL下载文件。
require 'aliyun/oss'
client = Aliyun::OSS::Client.new(
  # Endpoint以华东1(杭州)为例,其它Region请按实际情况填写。
  endpoint: 'https://oss-cn-hangzhou.aliyuncs.com',
  # 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
  access_key_id: ENV['OSS_ACCESS_KEY_ID'],
  access_key_secret: ENV['OSS_ACCESS_KEY_SECRET']
)
# 填写Bucket名称,例如examplebucket。
bucket = client.get_bucket('examplebucket')
# 生成预签名URL,并指定URL有效时间为1小时(3600秒)。
puts bucket.object_url('my-object', true, 3600)C
更多SDK信息,请参见C使用预签名URL下载文件。
#include "oss_api.h"
#include "aos_http_io.h"
/* yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。*/
const char *endpoint = "yourEndpoint";
/* 填写Bucket名称,例如examplebucket。*/
const char *bucket_name = "examplebucket";
/* 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。*/
const char *object_name = "exampledir/exampleobject.txt";
/* 填写本地文件的完整路径。*/
const char *local_filename = "yourLocalFilename";
void init_options(oss_request_options_t *options)
{
    options->config = oss_config_create(options->pool);
    /* 用char*类型的字符串初始化aos_string_t类型。*/
    aos_str_set(&options->config->endpoint, endpoint);
    /* 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。*/
    aos_str_set(&options->config->access_key_id, getenv("OSS_ACCESS_KEY_ID"));
    aos_str_set(&options->config->access_key_secret, getenv("OSS_ACCESS_KEY_SECRET"));
    /* 是否使用CNAME访问OSS服务。0表示不使用。*/
    options->config->is_cname = 0;
    /* 设置网络相关参数,例如超时时间等。*/
    options->ctl = aos_http_controller_create(options->pool, 0);
}
int main(int argc, char *argv[])
{
    /* 在程序入口调用aos_http_io_initialize方法来初始化网络、内存等全局资源。*/
    if (aos_http_io_initialize(NULL, 0) != AOSE_OK) {
        exit(1);
    }
    /* 用于内存管理的内存池(pool),等价于apr_pool_t。其实现代码在apr库中。*/
    aos_pool_t *pool;
    /* 重新创建一个内存池,第二个参数是NULL,表示没有继承其它内存池。*/
    aos_pool_create(&pool, NULL);
    /* 创建并初始化options,该参数包括endpoint、access_key_id、acces_key_secret、is_cname、curl等全局配置信息。*/
    oss_request_options_t *oss_client_options;
    /* 在内存池中分配内存给options。*/
    oss_client_options = oss_request_options_create(pool);
    /* 初始化Client的选项oss_client_options。*/
    init_options(oss_client_options);
    /* 初始化参数。*/
    aos_string_t bucket;
    aos_string_t object;
    aos_string_t file;    
    aos_http_request_t *req;
    apr_time_t now;
    char *url_str;
    aos_string_t url;
    int64_t expire_time; 
    int one_hour = 3600;
    aos_str_set(&bucket, bucket_name);
    aos_str_set(&object, object_name);
    aos_str_set(&file, local_filename);
    expire_time = now / 1000000 + one_hour;    
    req = aos_http_request_create(pool);
    req->method = HTTP_GET;
    now = apr_time_now();  
    /* 单位:微秒 */
    expire_time = now / 1000000 + one_hour;
    /* 生成预签名URL。*/
    url_str = oss_gen_signed_url(oss_client_options, &bucket, &object, expire_time, req);
    aos_str_set(&url, url_str);
    printf("临时下载URL: %s\n", url_str);     
    /* 释放内存池,相当于释放了请求过程中各资源分配的内存。*/
    aos_pool_destroy(pool);
    /* 释放之前分配的全局资源。*/
    aos_http_io_deinitialize();
    return 0;
}使用命令行工具ossutil
对存储空间examplebucket里的example.txt对象,生成有效期为1小时的预签名URL。
ossutil presign oss://examplebucket/example.txt --expires-duration 1h关于使用ossutil生成预签名URL的更多示例, 请参见presign(生成预签名URL)。
使用图形化管理工具ossbrowser
获取长期有效的链接
您可以通过以下两种方式获取不含签名、无过期时间限制的文件URL(链接)。
- 方式一:设置文件为公共读(不推荐) - 将文件ACL设置为"公共读",获取永久有效的文件URL。配置简单、无需额外工具,但文件地址完全公开,任何人都可访问,易被恶意爬虫或刷流量。建议配合OSS 防盗链(Referer白名单)使用,但仍存在源站暴露风险。 
- 方式二:通过CDN提供公共读访问(推荐) - 文件保持私有,通过CDN实现公共访问。开启CDN的OSS私有Bucket回源功能后,您可以通过CDN加速域名访问私有Bucket内的所有资源,原URL的私有鉴权方式将失效。相比方式一,OSS不直接暴露,安全性更高,支持加速与访问控制功能。建议启用CDN的Referer防盗链和URL鉴权,防止链接被滥用。 
如何拼接长期有效的文件URL
您可根据域名类型拼接文件访问地址。
| 域名类型 | URL格式 | 示例 | 
| OSS默认域名 | 
 | 例如,华东1(杭州)地域下名为examplebucket的Bucket下有名为example的文件夹,文件夹内有个名为example.jpg的文件。 
 | 
| 自定义域名 | 
 | 例如,您在华东1(杭州)地域下的examplebucket绑定了自定义域名 | 
| CDN加速域名 | 
 | 例如,当CDN加速域名为 | 
- <BucketName>:存储空间名称。
- <ObjectName>:文件的完整路径(如- folder/example.jpg)。
- <Endpoint>:所在地域的访问域名。
- <YourDomainName>:您的自定义域名。更多信息请参见绑定自定义域名至Bucket默认域名。
- <CDN 加速域名>:您的CDN加速域名。
配置HTTPS协议
链接协议由访问域名(Endpoint)决定。默认访问域名无需配置,直接支持HTTPS;使用自定义域名时,需先完成证书托管,才能启用 HTTPS 协议。
- OSS控制台:生成链接时,可在详情面板选择协议,默认即为 HTTPS。 
- ossutil/SDK:取决于您设置的 Endpoint。以 - https://开头,则使用 HTTPS。
预览.txt文件时中文乱码
在浏览器或OSS控制台中预览 .txt 文件时,如果出现中文乱码,通常是由于文件未声明正确的编码格式所致。您可以将文件元数据的Content-Type字段设置为text/plain;charset=utf-8,强制浏览器使用正确的UTF-8编码进行显示。
- 登录OSS管理控制台。 
- 单击Bucket 列表,然后单击目标Bucket名称。 
- 在左侧导航栏,选择。 
- 在目标Object右侧选择。 
- 在HTTP标准属性区域,将Content-Type设置为text/plain;charset=utf-8。 
- 单击确定保存设置。 
限制访问来源
通过配置Referer防盗链,只允许指定网站访问 OSS 资源,拒绝其他来源的请求。
例如,只允许来自您的官网https://example.com的访问请求,其他来源将被拒绝。
授权第三方更多操作
除了预签名URL,阿里云还提供了更灵活的临时授权方式——STS临时访问凭证。如果您希望第三方对OSS的操作不只是下载,还能执行如列举、拷贝等操作,建议您了解并使用STS临时访问凭证,详情请参见使用STS临时访问凭证访问OSS。
处理图片
您可以生成带图片处理参数的预签名URL来处理图片,例如调整大小,添加水印等。


