简述:海报二维码接口错误使用主题目录地址,修正接口入口为站点根 index.php
问题现象
开启文章分享海报功能后,海报上的二维码图片一直裂图。 F12 开发者工具查看图片 src,发现代码拼接出来的二维码地址挂载在了主题目录下:
https://example.com/usr/themes/handsome/?action=get_qr_code&type=url&content=https://example.com/index.php/xxx.html
这个地址是无法触发二维码生成逻辑的。
✅ 正确的接口入口应当是站点根目录的 index.php:
https://example.com/index.php/?action=get_qr_code&type=url&content=https://example.com/index.php/xxx.html
原因分析
二维码接口 get_qr_code,是主题通过 Typecho_Plugin::factory('index.php')->begin 钩子,监听根 index.php 的 GET 参数实现的自定义接口。
原来代码使用了 THEME_URL 常量拼接链接,而 THEME_URL 指向 /usr/themes/handsome/ 主题文件夹。访问主题目录下带 ?action= 参数的地址,不会进入这个钩子的处理逻辑,因此无法输出二维码图片。
划重点:这个接口不属于主题静态文件路由,也不是 Typecho 标准 PATHINFO 形式的 action,必须由根 index.php 接收参数才能生效。
源码定位与修改
文件路径:handsome/libs/Content.php
目标函数:returnSharePostDiv,这个函数负责渲染分享海报的 HTML 结构。
修改前(错误写法)
$image = THEME_URL . '?action=get_qr_code&type=url&content=' . $url;
修改后(修复写法)
$image = Helper::options()->rootUrl . '/index.php/?action=get_qr_code&type=url&content=' . $url;
改动要点:
- 放弃
THEME_URL,改用站点根地址Helper::options()->rootUrl; - 显式指定入口文件
/index.php/; - 使用
rawurlencode()对文章链接编码,防止链接中包含&、=等特殊符号,造成参数解析错乱。
操作步骤
- 打开主题内
libs/Content.php,找到returnSharePostDiv函数; - 将二维码图片地址那一行替换为修复后的代码;
- 保存文件;
- 清理 Typecho 后台缓存,浏览器强制刷新页面测试海报。
踩坑总结
THEME_URL代表主题目录,不适合拼接监听在根 index.php 的自定义接口;- 分清两套 action 路由,不要互相混淆:
index.php/?action=xxx:根 index 钩子实现的自定义 GET 接口(本次二维码接口属于这类)index.php/action/xxx:Typecho 原生 PATHINFO Action 路由
- Handsome 各个改版、二次修改版本的接口挂载位置差异很大,网上通用教程不能直接照搬,优先抓包验证接口真实地址;
- URL 作为 GET 参数传递时,编码
rawurlencode是必要的防护,避免参数被截断。
拓展:查找该版本全部 ?action= 接口
在主题源码里全局搜索关键词 $_GET['action'],找到 index.php->begin 钩子内的 switch 分支,该主题所有同类自定义 action 动作都写在这个代码块中。可以自行拼接地址测试是否可用,示例格式:
https://example.com/index.php/?action=动作名
配套摘要(直接复制进Handsome摘要框)
Handsome主题分享海报二维码裂图,根源是接口使用THEME_URL拼接到主题目录,将接口入口修正为根index.php,记录本次路由踩坑。