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
ossbrowser支援Object層級的操作與控制台支援的操作類似,請按照ossbrowser介面指引完成擷取預簽名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命令自動使用自訂網域名,而無需每次在命令中手動指定自訂網域名,您可以在設定檔中添加自訂網域名,
如果連結仍無法預覽,還需檢查以下配置。
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
ossbrowser支援Object層級的操作與控制台支援的操作類似,請按照ossbrowser介面指引完成擷取預簽名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。
預覽時中文亂碼
設定檔案中繼資料的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來處理圖片,例如調整大小,添加浮水印等。