You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google Cloud Storage含Unicode字符的Blob签名URL生成失败

Google Cloud Storage生成签名URL时Unicode文件名触发KeyError的解决方案

问题场景

测试GCS上传下载功能时,Blob名称仅含英文、空格或常规特殊字符时,生成签名URL正常;但使用包含Unicode字符(如阿拉伯语文件名جراج.png)时,触发KeyError: u'\u062c'错误。官方文档明确说明Blob名称支持任意有效Unicode序列(UTF-8编码后1-1024字节)。

相关代码

generate_download_signed_url_v4("storage_files", "202209/جراج.png")

def generate_download_signed_url_v4(bucket_name, blob_name):
    storage_client = storage.Client.from_service_account_json('s_account.json')
    bucket = storage_client.bucket(bucket_name)
    blob = bucket.blob(blob_name)
    
    url = blob.generate_signed_url(
        expiration=datetime.timedelta(minutes=10), # URL有效期10分钟
        method="GET", # 允许GET请求
    )
    
    print "Generated GET signed URL:", url
    return url

报错栈

Traceback (most recent call last):
  File "/Users/k/Documents/app30/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1529, in __call__
    rv = self.router.dispatch(request, response)
  File "/Users/k/Documents/app30/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1278, in default_dispatcher
    return route.handler_adapter(request, response)
  File "/Users/k/Documents/app30/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 1102, in __call__
    return handler.dispatch()
  File "/Users/k/Documents/app30/gae/users_app/helpers.py", line 68, in dispatch
    webapp2.RequestHandler.dispatch(self) # dispatch the main handler
  File "/Users/k/Documents/app30/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 572, in dispatch
    return self.handle_exception(e, self.app.debug)
  File "/Users/k/Documents/app30/google-cloud-sdk/platform/google_appengine/lib/webapp2-2.5.2/webapp2.py", line 570, in dispatch
    return method(*args, **kwargs)
  File "/Users/k/Documents/app30/gae/users_app/helpers.py", line 431, in check_admin
    return myfunction(self, *args, **kwargs)
  File "/Users/k/Documents/app30/gae/users_app/main.py", line 10796, in get
    my_file_link = self.generate_download_signed_url_v4(root_bucket_name, "572680296//202209/جراج.png")
  File "/Users/k/Documents/app30/gae/users_app/main.py", line 10863, in generate_download_signed_url_v4
    method="GET", # Allow GET requests using this URL.
  File "/Users/k/Documents/app30/gae/users_app/lib/google/cloud/storage/blob.py", line 338, in generate_signed_url
    quoted_name=quote(self.name))
  File "/Users/k/Documents/app30/google-cloud-sdk/platform/google_appengine/google/appengine/dist27/urllib.py", line 1294, in quote
    return ''.join(map(quoter, s))
KeyError: u'\u062c'
*******> Exception: u'\u062c'

当前使用本地开发服务器版本v.340。

原因分析

报错根源是Python 2.7环境下App Engine内置的urllib.quote函数不支持直接处理Unicode字符串,遇到非ASCII Unicode字符时会抛出KeyError。GCS客户端库生成签名URL时,内部调用了该旧版quote方法,导致编码失败。

修复方案

手动对Unicode格式的Blob名称进行UTF-8编码,再传入签名URL生成逻辑,或直接指定编码后的quoted_name参数覆盖内部处理:

修改后的代码

from urllib import quote
import datetime
from google.cloud import storage

generate_download_signed_url_v4("storage_files", "202209/جراج.png")

def generate_download_signed_url_v4(bucket_name, blob_name):
    storage_client = storage.Client.from_service_account_json('s_account.json')
    bucket = storage_client.bucket(bucket_name)
    
    # 将Unicode文件名转换为UTF-8字节串,兼容旧版urllib处理
    blob_name_utf8 = blob_name.encode('utf-8')
    blob = bucket.blob(blob_name_utf8)
    
    # 手动生成URL编码后的文件名,避免内部调用报错的quote方法
    quoted_name = quote(blob_name_utf8)
    
    url = blob.generate_signed_url(
        expiration=datetime.timedelta(minutes=10),
        method="GET",
        quoted_name=quoted_name  # 传入手动编码的文件名
    )
    
    print "Generated GET signed URL:", url
    return url

说明

  1. 先将Unicode类型的Blob名称编码为UTF-8字节串,确保旧版urllib.quote能正确处理;
  2. 通过quoted_name参数手动传入编码后的文件名,绕过客户端库内部可能出错的编码逻辑;
  3. 该方案适配Python 2.7 + App Engine本地服务器v340的环境,同时符合GCS对Unicode文件名的支持规范。

内容的提问来源于stack exchange,提问作者Khaled

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 15:55:16