全部產品
Search
文件中心

Object Storage Service:自訂OSS檔案下載時的檔案名稱

更新時間:Jun 19, 2024

在OSS中,檔案名稱一旦確定,就會作為唯一標識而不可更改。因此,這些檔案名稱常常是基於UUID等非直觀規則進行命名,以確保它們的唯一性。當您需要確保使用者在下載檔案時看到的是一個有意義的、易於識別的名稱時,您可以通過預簽名URL的response-content-disposition參數來指定某檔案單次下載請求的檔案名稱,或修改檔案的Content-Disposition中繼資料來指定某檔案所有下載請求的檔案名稱。

OSS檔案下載時檔案名稱的顯示優先順序

檔案下載時顯示的檔案名稱由以下因素決定:

  1. 預簽名URL的response-content-disposition參數: 使用預簽名URL並指定response-content-disposition參數時,該參數覆蓋檔案中繼資料中的Content-Disposition設定。

  2. 檔案中繼資料中的Content-Disposition欄位: 如果未通過預簽名URL指定,將檢查檔案的中繼資料中的Content-Disposition欄位。

  3. OSS檔案名稱: 如果上述兩者都未設定,將預設使用對象鍵名的檔案名稱部分。

通過預簽名URL設定單次下載的檔案名稱

預簽名URL是OSS提供的一種臨時授權訪問連結,可以讓使用者在一定時間內下載私人許可權的檔案。通過在產生預簽名URL的過程中添加response-content-disposition參數,您可以控制使用者在本次下載檔案時看到的檔案名稱,而不需要修改檔案中繼資料中的Content-Disposition欄位或OSS檔案名稱。

使用情境

  • 臨時檔案分享權限設定:當您想要與特定使用者分享一個檔案,並且希望該使用者在下載時看到一個特定的檔案名稱,而不是儲存在OSS上的原始檔案名。

  • 個人化下載:如果您要為不同的使用者提供個人化的檔案名稱,例如根據使用者的姓名或訂單號產生的檔案名稱,可以使用預簽名URL的方式來實現。

  • 測試和預覽:如果您想要提供一份檔案供使用者預覽或測試,但並不想改變該檔案的原始或預設下載名稱。

許可權說明

要產生用於下載檔案的預簽名URL,您必須具有oss:GetObject許可權。具體操作,請參見為RAM使用者授權自訂的權限原則

注意事項

  • response-content-disposition參數是在產生預簽名URL時指定的,只對該URL有效。

  • 確保在指定檔案名稱時使用URL編碼,避免特殊字元造成的問題。

  • 預簽名URL有有效期間,到期後無法使用,確保提供給使用者的URL在他們下載檔案之前是有效。

  • 如果OSS中的檔案已經設定了Content-Disposition,使用預簽名URL內的response-content-disposition將臨時覆蓋它。

範例程式碼

產生預簽名URL的過程中添加response-content-disposition參數的Python範例程式碼如下:

# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
from urllib.parse import quote

# 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())

# yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
# 填寫Bucket名稱。
bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', '<bucket_name>')

# 填寫Object完整路徑,例如exampledir/exampleobject.txt。Object完整路徑中不能包含Bucket名稱。
object_name = 'exampledir/exampleobject.txt'

# 使用者下載時希望看到的檔案名稱,這裡需要進行URL編碼。
download_filename = quote('desired-filename.txt')

# 設定回應標頭中的Content-Disposition,指定下載時使用的檔案名稱。
params = {'response-content-disposition': f'attachment; filename="{download_filename}"'}

# 產生下載檔案的簽名URL,有效時間為3600秒。
# 設定slash_safe為True,OSS不會對Object完整路徑中的正斜線(/)進行轉義,此時產生的簽名URL可以直接使用。
url = bucket.sign_url('GET', object_name, 3600, params=params, slash_safe=True)

print('簽名URL的地址為:', url)

更多語言的範例程式碼,請參見使用檔案URL分享檔案

通過檔案中繼資料設定所有下載的檔案名稱

在OSS中,Content-Disposition頭部用於指定對象被下載時的預設檔案名稱。當您希望某個檔案的所有下載請求都使用新的檔案名稱時,您可以更新檔案的中繼資料中的Content-Disposition欄位,而不需要修改檔案在OSS上的實際檔案名稱。一旦修改了Content-Disposition,所有未指定response-content-disposition參數的下載請求都將看到新設定的檔案名稱。

使用情境

  • 長期檔案分享權限設定:當檔案需要被多次下載,並且每次下載都希望顯示相同檔案名稱時,通過修改檔案中繼資料可以實現這一目標。

  • 文件庫或資源中心:在企業的文件庫或公用資源中心中,您可能希望所有檔案都具有固定的、描述性的檔案名稱,方便識別和歸檔。

  • 持久性產品更新:如果您定期更新產品文檔或軟體,希望使用者始終通過同一個連結下載最新版本,且檔案名稱保持不變,可以通過設定中繼資料來實現。

許可權說明

要修改檔案中繼資料,您必須具有oss:PutObject許可權。具體操作,請參見為RAM使用者授權自訂的權限原則

注意事項

  • 確保在設定Content-Disposition時考慮檔案名稱中可能的特殊字元,並進行適當的URL編碼。

  • 更新Content-Disposition是通過PUT操作覆蓋現有對象的中繼資料來實現的。如果您希望保留除Content-Disposition以外的其他中繼資料,您需要首先擷取對象的當前中繼資料,對其進行必要的修改,然後使用更新後的中繼資料集合一起執行PUT操作。

  • 為了避免重新上傳整個對象內容並減少資料覆蓋的風險,推薦使用SDK中的update_object_meta介面而非PutObject介面來安全地更新對象的中繼資料。

範例程式碼

更新檔案的中繼資料中的Content-Disposition欄位的Python範例程式碼如下:

# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
from urllib.parse import quote

# 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())

# yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
# 填寫Bucket名稱。
bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', '<bucket_name>')

# 填寫Object完整路徑,例如exampledir/exampleobject.txt。Object完整路徑中不能包含Bucket名稱。
object_name = 'exampledir/exampleobject.txt'

# 使用者下載時希望看到的檔案名稱,這裡需要進行URL編碼。
download_filename = quote('desired-filename.txt')

# 更新檔案中繼資料,設定下載時的檔案名稱。
# 注意:此更新操作會替換掉對象的所有中繼資料。
# 如果您想保留其他已有的中繼資料,需要先擷取現有的中繼資料,
# 然後進行修改,並將完整的中繼資料集合一起更新。
headers = {'Content-Disposition': f'attachment; filename="{download_filename}"'}
bucket.update_object_meta(object_name, headers)

更多語言的範例程式碼,請參見管理檔案中繼資料