前些天对 Typecho 进行了简单的改造,以支持 WebP,正文部分非常顺利,但随后发现时光机仍不支持,上传即报错,检查代码,发现作者限制了上传类型。

源代码:

if (files[0].type!=="image/jpeg" && files[0].type!=="image/png" && files[0].type!=="image/gif"){
    $("#file-info").val("错误的文件类型!" + files[0].type);
    return;
}

添加 WebP 类型之后,上传成功:

if (files[0].type!=="image/webp" && files[0].type!=="image/jpeg"

只是此时返回的不是 WebP,而是 JPG,文件体积比 WebP 还小,压缩算法很不错。我们也不必纠结格式,毕竟终极目标是为了节约硬盘空间,提升加载速度。

我想着这不是太复杂的操作,不必写文章记录,只发了一条时光机,贴上修改后的代码作个纪念。但不久之后就发现问题,时光机输入框,按 # 之后,无法弹出标签提示。控制台报错:

TAGLIST.webp

我就很困惑,我并没有修改 JavaScript,为何会报 JSON 解析错误?我尝试把文件还原,清理缓存,错误仍在。也曾开口求助,无奈对方并不熟悉程序结构和来龙去脉,无法提供有效方案,只能自己摸索解决。

JSON 错误,如果不是代码本身出错,那就是应用返回的 JSON 数据有错,而我未修改过代码,那大概率还是数据错误。于是我删除了最新发表的几条时光机,问题依旧。最后无意识的打开了标签列表,才发出多出了一个标签:

#file-info").val("错误的文件类型!"

标签里的引号,足以让 JSON 解析失败。一定是我在插入代码时,jQuery ID 选择器被识别为标签前缀,插入了数据库,而删除时光机条目,并不会删除关联的标签,问题就出现了。这个故障困扰我三个小时,现在回想起来,其实本该更早定位的,因为浏览器已经明确提示,JSON 解析失误,而标签提示无法加载,就是获取不到正确的标签列表,第一时间检查标签就好了。

春节之前,我给时光机的标签添加了 Emoji 表情,与文字相映成趣,但页面右侧全部标签排列在一起,显得过于花哨,于是我将标签版块默认折叠了,很少打开来看。这个改动一定程度上延误了我发现问题。

但这不是借口,分析问题,更应该依靠主动的逻辑推理,而不是被动的视觉发现。

问题根源找到了,解决起来就容易了,非法标签,前台也无法删除,因为一切操作都依赖 JSON 解析,登录数据库,SQL 操作:

SELECT * FROM typecho_handsometag;
DELETE FROM typecho_handsometag WHERE tid = 28;

故障完美解决。

附解析标签的代码片段:

initTribute: function() {
    const a = this;
    handsome_util.addScript("https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/tributejs/5.1.3/tribute.min.js", "tribute_js", function() {
        a.getOnlineTagList(function() {
            a.tribute = new Tribute(a.tag_options),
            a.tribute.attach(document.getElementById("comment"))
        })
    })
},
getOnlineTagList: function(a) {
    this.tag_options.values = JSON.parse(LocalConst.TAG_LIST),//报错
    a && a()
    },
addTag: function(a) {},
editTag: function(a, b) {},
deleteTag: function(a) {},

源代码进行了压缩和混淆,Safari 浏览器很好的进行了格式化还原,必须为这个功能点赞。

这次故障给我的教训:永远要从程序和数据两个方向,思考问题的解决方案,不可死守一端。

最后修改:2023 年 01 月 31 日
如果觉得我的文章对你有用,请随意赞赏