自定义OSS文件下载时的文件名

在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)

更多语言的示例代码,请参见管理文件元数据