网站Bug修复

我真没想到这会是一个系列...(已裂开)

4 篇文章 @meli
第 4 篇 / 共 4 篇
在新页面打开 →
@meli Bug修复

还是Bug()

2026年7月20日 1233 字

在生成默认头像的逻辑中,调用了Dicebear的API,大致逻辑如下:

def generate_default_avatar(profile):
    """Fetch DiceBear PNG for the user, convert to WebP, store locally.
    Best-effort: silently returns False on network/image errors.
    """
    from urllib.request import urlopen, Request
    from urllib.error import URLError
    from django.core.files.base import ContentFile

    url = f"https://api.dicebear.com/7.x/bottts/png?seed={profile.user.username}&size=256"
    try:
        req = Request(url, headers={"User-Agent": "MeLi Cosmos/1.0"})
        with urlopen(req, timeout=5) as resp:
            raw = resp.read()
    except (URLError, OSError):
        return False

    # 省略:头像处理与保存逻辑
    # ……

    return True

问题是,在 HTTP/1.1 协议规范(RFC 7230)中明确规定:HTTP 请求行(Request Line)和请求头(Headers)必须是纯 ASCII 字符(0-127)。所以,Python底层标准库http.client在发送请求前,会执行一个严格的编码检查;一旦注册时的username包含非ASCII字符(如中文字符)并被直接拼接进URL,http.client会直接抛出 UnicodeEncodeError,导致服务崩溃。

不过修复倒是比较好办,加一个quote()函数将非ASCII字符用URL百分号编码即可:

    from urllib.parse import quote
    url = f"https://api.dicebear.com/7.x/bottts/png?seed={quote(profile.user.username)}&size=256"

不过有趣的是,四个人甚至没有一个尝试任何非ASCII字符,间接导致bug保留至今🤣

已紧急修复 20260720

#Bug