# 在 URL 中是片段标识符(Fragment Identifier)的开始标志,如果不处理,# 后面的内容会被浏览器或解析器直接忽略,导致密码被截断,连接失败。
❌ 错误示例(会出问题)
python
# ❌ 这样写,实际密码会变成 "abc",后面的内容全部丢失
Redis.from_url("redis://:abc#123@localhost:6379/0")
实际解析结果:
- 你以为的密码:
abc#123 - 实际解析到的密码:
abc #123被当成了 URL 的 fragment,直接丢弃
✅ 正确做法:URL 编码(Percent-Encoding)
# 的 URL 编码是 %23
python
from redis import Redis
# ✅ 正确写法
redis_client = Redis.from_url("redis://:abc%23123@localhost:6379/0")
🔧 推荐:使用 urllib 自动编码(最稳妥)
如果是从配置文件、环境变量里读密码,强烈建议用代码自动编码,避免手写出错。
python
from urllib.parse import quote_plus
from redis import Redis
password = "abc#123"
encoded_password = quote_plus(password)
url = f"redis://:{encoded_password}@localhost:6379/0"
redis_client = Redis.from_url(url)
redis_client.ping()
print("✅ 连接成功")
📌 常见需要编码的特殊字符速查表
| 字符 | 含义 | URL 编码 |
|---|---|---|
# |
片段标识 | %23 |
@ |
分隔符 | %40 |
: |
分隔符 | %3A |
/ |
路径分隔 | %2F |
% |
本身 | %25 |
+ |
空格 | %2B |
(空格) |
空格 | %20 |
👉 只要密码里有非字母数字字符,都建议直接 quote_plus()
✅ 更推荐的写法(避免 URL 拼接问题)
如果你不想折腾 URL 编码,直接用参数方式(内部会自动处理):
python
from redis import Redis
redis_client = Redis(
host="localhost",
port=6379,
db=0,
password="abc#123", # ✅ 原样写,最安全
decode_responses=True
)
📌 生产环境强烈推荐这种方式,可读性最好,坑最少。
🐳 Docker / Kubernetes / 云环境注意事项
如果是从环境变量读取:
python
import os
from urllib.parse import quote_plus
from redis import Redis
raw_password = os.getenv("REDIS_PASSWORD") # abc#123
redis_client = Redis.from_url(
f"redis://:{quote_plus(raw_password)}@redis:6379/0"
)
✅ 总结一句话
Redis 密码里有
#,必须 URL 编码成%23,否则密码会被截断。最佳实践:不用
from_url()拼密码,改用Redis(password="xxx")参数方式。