Google Cloud Storage自定义元数据未在响应头中出现问题排查
问题
我在Google Cloud Storage(GCS)控制台完成了以下操作:
- 创建了带有公共访问限制的标准存储类型存储桶
- 在桶内上传了一个小文件,并通过GUI添加了自定义元数据(
"name":"jack") - 编写了如下Python脚本用于下载该文件:
from pathlib import Path import requests def url_retrieve(url: str, outfile: Path): R = requests.get(url, allow_redirects=True) if R.status_code != 200: raise ConnectionError('could not download {}\nerror code: {}'.format(url, R.status_code)) print(R.history) print(R.headers) print(R.status_code) outfile.write_bytes(R.content) url_retrieve(url, path)
我传入的URL来自GCS控制台中对象的Authenticated URL字段,但响应头中未包含我添加的自定义元数据,示例响应头如下:
Content-Type: text/html; charset=utf-8
X-Frame-Options: DENY
Set-Cookie: __Host-GAPS=1:YbfLYYNRk-YoqA4WaishOZQsoWZyKg:Mgn4RZDSaVcAMUG4; Expires=Wed, 07-May-2025 08:51:52 GMT; Path=/; Secure; HttpOnly; Priority=HIGH
x-auto-login: realm=com.google&args=service%3Dcds%26continue%3Dhttps://storage.cloud.google.com/kravtsov-test-bucket/tox_01.tox
x-ua-compatible: IE=edge
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: Mon, 01 Jan 1990 00:00:00 GMT
Date: Mon, 08 May 2023 08:51:52 GMT
Strict-Transport-Security: max-age=31536000; includeSubDomains
Cross-Origin-Opener-Policy-Report-Only: same-origin; report-to="AccountsSignInUi"
Content-Security-Policy: script-src 'report-sample' 'nonce-4gxVLMlbGh5kkUnB0MDL4g' 'unsafe-inline';object-src 'none';base-uri 'self';report-uri /v3/signin//AccountsSignInUi/cspreport;worker-src 'self'
Content-Security-Policy: require-trusted-types-for 'script';report-uri /v3/signin//AccountsSignInUi/cspreport
Accept-CH: Sec-CH-UA-Arch, Sec-CH-UA-Bitness, Sec-CH-UA-Full-Version, Sec-CH-UA-Full-Version-List, Sec-CH-UA-Model, Sec-CH-UA-WoW64, Sec-CH-UA-Platform, Sec-CH-UA-Platform-Version
Cross-Origin-Resource-Policy: same-site
Report-To: {"group":"AccountsSignInUi","max_age":2592000,"endpoints":[{"url":"https://csp.withgoogle.com/csp/report-to/AccountsSignInUi"}]}
Permissions-Policy: ch-ua-arch=, ch-ua-bitness=, ch-ua-full-version=, ch-ua-full-version-list=, ch-ua-model=, ch-ua-wow64=, ch-ua-platform=, ch-ua-platform-version=
Server: ESF
X-XSS-Protection: 0
X-Content-Type-Options: nosniff
Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
Accept-Ranges: none
Vary: Sec-Fetch-Dest, Sec-Fetch-Mode, Sec-Fetch-Site,Accept-Encoding
Connection: close
Transfer-Encoding: chunked
请问我哪里操作有误?
原因及解决办法
1. 核心错误:用错了URL类型
你使用的Authenticated URL是用于引导用户通过Google账号登录访问对象的网页跳转链接,并非直接获取对象内容的API访问链接。从响应头能看出,请求返回的是登录页面的HTML内容,而非目标文件,因此不会包含对象的自定义元数据。
2. 正确的URL获取方式
需要获取GCS对象的签名URL(Signed URL):
在GCS控制台的对象详情页,点击「生成签名URL」,设置有效期后生成的链接才是用于直接访问对象内容的授权链接。
3. 自定义元数据的返回规则
GCS返回自定义元数据时,会自动给键名添加x-goog-meta-前缀,比如你设置的name会以x-goog-meta-name: jack的形式出现在响应头中。
4. 脚本调整建议
如果使用签名URL,原脚本无需大幅修改,直接替换URL即可。如果想更便捷地处理GCS对象,推荐使用官方的google-cloud-storage库:
from pathlib import Path from google.cloud import storage def download_with_metadata(bucket_name: str, blob_name: str, outfile: Path): storage_client = storage.Client() bucket = storage_client.bucket(bucket_name) blob = bucket.blob(blob_name) # 获取自定义元数据 metadata = blob.metadata print("自定义元数据:", metadata) # 下载文件 blob.download_to_filename(outfile) download_with_metadata("your-bucket-name", "your-file-name", Path("./downloaded-file"))
内容的提问来源于stack exchange,提问作者Евгений Кравцов

