Files
SimpleNav/admin/fetch_meta.php
T
laoyang 4ba512b147 fix: 图标文件名按「整条网址」命名,同域名不同路径不再互相覆盖
https://nas.yangyq.net/calendar 与 https://nas.yangyq.net/ 这类「同域名、
不同路径」的条目,图标文件名原先只由域名决定(md5(域名)),两条记录指向
同一个文件:改其中一个的自定义图标,另一个跟着变;保存时还会 unlink /
覆盖掉对方的文件,直接把对方搞成破图。

- 新增 icon_key($url):按整条网址取键(协议与主机名转小写、空路径补 /、
  查询串与锚点保留),语义是「不同网址 → 不同图标文件」。
- 4 处调用点全部改用它:site_save(上传图标 / 自定义地址)、fetch_meta、
  update_all;键一律取自「记录里存的那条 URL」,不用跳转后的 final_url,
  保证同一个网站每次算出来的键都一样(否则每次重下 + 留下孤儿文件)。
- download_best_icon() / save_custom_icon() 增加空键保护,避免键为空时
  所有图标都落到同一个文件名上。
- README 新增「图标文件的命名规则」一节。
- .gitattributes 统一按 LF 存放,防止 Windows 的 core.autocrlf 在下次
  checkout 时把 PHP/JS/CSS 换成 CRLF。
- e2e 新增「同域名不同路径」回归场景:用三张颜色不同的图,比对两条记录
  落盘图标的内容,验证改 A 不会波及 B;并已做反向验证(把 icon_key 改回
  按域名取键后,这些断言确实失败)。
2026-09-28 17:26:40 +08:00

39 lines
1.4 KiB
PHP

<?php
/**
* 简航 SimpleNav —— 添加/编辑网站时自动抓取元信息(供后台 AJAX 调用)
* 流程:访问网址拿标题 → 解析页面/ manifest 里的高分辨率图标候选 → 择优下载到本地
* 返回:{ ok, name, short, icon, icon_url, candidates, url }
*/
declare(strict_types=1);
require_once __DIR__ . '/_auth.php';
require_login();
send_no_cache();
header('Content-Type: application/json; charset=utf-8');
$url = isset($_GET['url']) ? norm_url((string)$_GET['url']) : '';
if ($url === '') {
echo json_encode(['ok' => false, 'msg' => '缺少网址'], JSON_UNESCAPED_UNICODE);
exit;
}
$meta = fetch_site_meta($url);
$domain = domain_of($meta['final_url'] ?: $url);
// 图标文件名按「用户填的那条网址」算,不用 final_url —— 否则站点日后每次抓取
// (或跳转变化)都会算出不同的键,重复下载、留下孤儿文件。
$iconFile = download_best_icon($meta['icons'], icon_key($url));
$name = $meta['name'] !== '' ? $meta['name'] : ($meta['title'] !== '' ? $meta['title'] : $domain);
echo json_encode([
'ok' => true,
'url' => $url,
'final_url' => $meta['final_url'],
'name' => $name,
'short' => $name,
'title' => $meta['title'],
'icon' => $iconFile,
'icon_url' => $iconFile !== '' ? icon_src($iconFile) : '',
'candidates' => count($meta['icons']),
], JSON_UNESCAPED_UNICODE);