简述:海报二维码接口错误使用主题目录地址,修正接口入口为站点根 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;

改动要点:

  1. 放弃 THEME_URL,改用站点根地址 Helper::options()->rootUrl;
  2. 显式指定入口文件 /index.php/;
  3. 使用 rawurlencode() 对文章链接编码,防止链接中包含 &、= 等特殊符号,造成参数解析错乱。

操作步骤

  1. 打开主题内 libs/Content.php,找到 returnSharePostDiv 函数;
  2. 将二维码图片地址那一行替换为修复后的代码;
  3. 保存文件;
  4. 清理 Typecho 后台缓存,浏览器强制刷新页面测试海报。

踩坑总结

  1. THEME_URL 代表主题目录,不适合拼接监听在根 index.php 的自定义接口;
  2. 分清两套 action 路由,不要互相混淆:
    • index.php/?action=xxx:根 index 钩子实现的自定义 GET 接口(本次二维码接口属于这类)
    • index.php/action/xxx:Typecho 原生 PATHINFO Action 路由
  3. Handsome 各个改版、二次修改版本的接口挂载位置差异很大,网上通用教程不能直接照搬,优先抓包验证接口真实地址;
  4. URL 作为 GET 参数传递时,编码 rawurlencode 是必要的防护,避免参数被截断。

拓展:查找该版本全部 ?action= 接口

在主题源码里全局搜索关键词 $_GET['action'],找到 index.php->begin 钩子内的 switch 分支,该主题所有同类自定义 action 动作都写在这个代码块中。可以自行拼接地址测试是否可用,示例格式:

https://example.com/index.php/?action=动作名

配套摘要(直接复制进Handsome摘要框)

Handsome主题分享海报二维码裂图,根源是接口使用THEME_URL拼接到主题目录,将接口入口修正为根index.php,记录本次路由踩坑。

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