系列:网站Bug修复
(第 4 篇 / 共 4 篇)
BUG修复
还是Bug()
📝 修改于 2026年7月20日 20:33
⏱️ 阅读时间 1 分钟
👁️ 浏览 5 次
🔑 UUID: 60527d12-ca6e-4d91-aa...
在生成默认头像的逻辑中,调用了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
CC BY-NC 4.0署名-非商业性使用 4.0 国际
Tresssed 赞了