遇到的问题
在使用 Dream2.0 Plus 主题时,友链页面里,有几个博主的头像怎么都刷不出来,F12 一看全是 400 Bad Request。
奇怪的是,把头像链接复制到浏览器地址栏直接打开,图片又是正常的。而且不是所有头像都坏,只有部分挂了。
后台检查了一圈,发现规律:头像 URL 带中文路径的才会炸。

排查原因
查看代码后终于发现了根本原因所在:双重编码问题(核心问题)。
控制台报错如下:
GET https://www.example.ccom/upload/%25E5%25A4%25B4%25E5%2583%258F.png 400 (Bad Request)注意 URL 里的
%25——这是%被再次编码的结果。
原代码中:
function setSafeSrc(element, url) {
var isSafe = /^(https?|data:image\/[a-z]+;base64|\/)/i.test(url)
element.src = isSafe ? encodeURI(url) : '' 当 URL 已经是编码状态(如 %E5%A4%B4%E5%83%8F.png ), encodeURI() 会再次编码,变成了 %25E5%25A4%25B4%25E5%2583%258F.png 。
编码过程变成了这样:
原始中文: 头像.png
一次编码后: %E5%A4%B4%E5%83%8F.png ← 正确的
二次编码后: %25E5%25A4%25B4%25E5%2583%258F.png ← % 被编码成 %25,炸了解决方案
修改位置
文件 : templates/links.html
行号 :第 8-12 行( setSafeSrc 函数)
function setSafeSrc(element, url) {
// 允许:http/https/data:image 协议 或 相对路径(以/开头)
var isSafe = /^(https?|data:image\/[a-z]+;base64|\/)/i.test(url)
element.src = isSafe ? encodeURI(url) : '' // 不安全则清空
}修改为:
function setSafeSrc(element, url) {
// 空值检查:防止 url 为空或 undefined 时报错
if (!url) { element.src = ''; return; }
// 安全协议检查:只允许 http/https/data:image/相对路径
var isSafe = /^(https?|data:image\/[a-z]+;base64|\/)/i.test(url);
if (!isSafe) { element.src = ''; return; }
// 编码检测:检查URL是否已包含 %XX 格式的编码字符
// 如果已编码则直接使用,避免双重编码导致 400 Bad Request
// 如果未编码则使用 encodeURI() 处理中文等特殊字符
element.src = /%[0-9A-Fa-f]{2}/.test(url) ? url : encodeURI(url);
}修改说明
修改内容 如下:
增加空值检查
增加已编码 URL 检测
条件执行
encodeURI()
修复效果 :解决了中文头像 URL 无法显示的问题,同时兼容已编码 URL 的情况。
验证修改
修改保存后,进入后台 Dream2.0 Plus 主题设置
执行清理模板缓存
刷新前台友链页面,中文头像正常显示
这个坑的本质是前端编码逻辑没有考虑输入状态。如果 URL 来自用户输入或数据库,可能已经是编码态,也可能是原始态,直接 encodeURI 会埋雷。
判断逻辑很简单:有 %XX 就不编码,没有才编码。搞定!
Dream2.0 Plus 友链头像 400 错误:双重编码陷阱排查
https://wuqishi.com/archives/dream2-plus-avatar-double-encoding-fix
评论