From 4112bb23f1eb1627f7605b31991f9399b2df04fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8C=E5=8F=89=E6=A0=91=E6=A0=91?= Date: Sat, 11 Oct 2025 19:42:12 +0800 Subject: [PATCH] =?UTF-8?q?update:=20=E6=9B=B4=E6=96=B0Umami=20API?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=E5=92=8C=E5=93=8D=E5=BA=94=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=A4=84=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 更新Umami API基础URL至自定义域名,并调整API路径以适配v3版本 修改统计数据获取逻辑以匹配新版API响应格式 更新文档说明以反映API变更 --- public/js/umami-share.js | 2 +- src/components/PostCard.astro | 6 ++--- src/components/PostMeta.astro | 6 ++--- src/components/widget/Profile.astro | 6 ++--- src/config.ts | 2 +- src/content/posts/static-view.md | 41 ++++++++++++----------------- 6 files changed, 28 insertions(+), 35 deletions(-) diff --git a/public/js/umami-share.js b/public/js/umami-share.js index 5aefc823c..0078f50d3 100644 --- a/public/js/umami-share.js +++ b/public/js/umami-share.js @@ -14,7 +14,7 @@ localStorage.removeItem(cacheKey); } } - const res = await fetch(`${baseUrl}/api/share/${shareId}`); + const res = await fetch(`${baseUrl}/analytics/us/api/share/${shareId}`); if (!res.ok) { throw new Error('获取 Umami 分享信息失败'); } diff --git a/src/components/PostCard.astro b/src/components/PostCard.astro index 53d0d88de..72e845d56 100644 --- a/src/components/PostCard.astro +++ b/src/components/PostCard.astro @@ -130,7 +130,7 @@ const { remarkPluginFrontmatter } = await entry.render(); // 第二步:获取统计数据 const currentTimestamp = Date.now(); - const statsUrl = `${umamiConfig.baseUrl}/api/websites/${websiteId}/stats?startAt=0&endAt=${currentTimestamp}&unit=hour&timezone=${encodeURIComponent(umamiConfig.timezone)}&url=%2Fposts%2F${slug}%2F&compare=false`; + const statsUrl = `${umamiConfig.baseUrl}/analytics/us/api/websites/${websiteId}/stats?startAt=0&endAt=${currentTimestamp}&unit=hour&timezone=${encodeURIComponent(umamiConfig.timezone)}&path=eq.%2Fposts%2F${slug}%2F&compare=false`; const statsResponse = await fetch(statsUrl, { headers: { @@ -148,8 +148,8 @@ const { remarkPluginFrontmatter } = await entry.render(); } const statsData = await statsResponse.json(); - const pageViews = statsData.pageviews?.value || 0; - const visits = statsData.visits?.value || 0; + const pageViews = statsData.pageviews || 0; + const visits = statsData.visitors || 0; const displayElement = document.getElementById(`page-views-${slug}`); if (displayElement) { diff --git a/src/components/PostMeta.astro b/src/components/PostMeta.astro index 48f7d284b..535a5e1b6 100644 --- a/src/components/PostMeta.astro +++ b/src/components/PostMeta.astro @@ -95,7 +95,7 @@ const className = Astro.props.class; // 第二步:获取统计数据 const currentTimestamp = Date.now(); - const statsUrl = `${umamiConfig.baseUrl}/api/websites/${websiteId}/stats?startAt=0&endAt=${currentTimestamp}&unit=hour&timezone=${encodeURIComponent(umamiConfig.timezone)}&url=%2Fposts%2F${slug}%2F&compare=false`; + const statsUrl = `${umamiConfig.baseUrl}/analytics/us/api/websites/${websiteId}/stats?startAt=0&endAt=${currentTimestamp}&unit=hour&timezone=${encodeURIComponent(umamiConfig.timezone)}&path=eq.%2Fposts%2F${slug}%2F&compare=false`; const statsResponse = await fetch(statsUrl, { headers: { @@ -112,8 +112,8 @@ const className = Astro.props.class; } const statsData = await statsResponse.json(); - const pageViews = statsData.pageviews?.value || 0; - const visits = statsData.visits?.value || 0; + const pageViews = statsData.pageviews || 0; + const visits = statsData.visitors || 0; const displayElement = document.getElementById('page-views-display'); if (displayElement) { diff --git a/src/components/widget/Profile.astro b/src/components/widget/Profile.astro index e95dccab3..905d9e176 100644 --- a/src/components/widget/Profile.astro +++ b/src/components/widget/Profile.astro @@ -63,7 +63,7 @@ const config = profileConfig; // 第二步:获取全站统计数据(不指定url参数获取全站数据) const currentTimestamp = Date.now(); - const statsUrl = `${umamiConfig.baseUrl}/api/websites/${websiteId}/stats?startAt=0&endAt=${currentTimestamp}&unit=hour&timezone=${encodeURIComponent(umamiConfig.timezone)}&compare=false`; + const statsUrl = `${umamiConfig.baseUrl}/analytics/us/api/websites/${websiteId}/stats?startAt=0&endAt=${currentTimestamp}&unit=hour&timezone=${encodeURIComponent(umamiConfig.timezone)}&compare=false`; const statsResponse = await fetch(statsUrl, { headers: { @@ -82,8 +82,8 @@ const config = profileConfig; } const statsData = await statsResponse.json(); - const pageviews = statsData.pageviews?.value || 0; - const visitors = statsData.visits?.value || 0; + const pageviews = statsData.pageviews || 0; + const visitors = statsData.visitors || 0; const statsElement = document.getElementById('site-stats'); if (statsElement) { diff --git a/src/config.ts b/src/config.ts index 01f389be0..4aaad62e9 100644 --- a/src/config.ts +++ b/src/config.ts @@ -118,7 +118,7 @@ export const imageFallbackConfig: ImageFallbackConfig = { export const umamiConfig: UmamiConfig = { enable: true, - baseUrl: "https://cloud.umami.is", + baseUrl: "https://umami.2b2x.cn", shareId: "hN3l7PGcxsUCBHfU", timezone: "Asia/Shanghai", }; diff --git a/src/content/posts/static-view.md b/src/content/posts/static-view.md index 53235fc55..be2dc2884 100644 --- a/src/content/posts/static-view.md +++ b/src/content/posts/static-view.md @@ -25,7 +25,7 @@ lang: '' 现在我们确实可以看到每个文章(即/posts/xxx)的访问量了,但是我们要如何展示给用户呢? -# 逆向Umami的只读页面! +# 逆向Umami的只读页面!(新版v3) > 感谢nightNya提供的方案,你是天才! @@ -35,7 +35,8 @@ lang: '' 注意这里的 `7PoDRgCzHFTs2vWB` ,每个站点都不一样 -接着我们请求 `https://us.umami.is/api/share/7PoDRgCzHFTs2vWB`,得到 +接着我们请求 `https://cloud.umami.is/analytics/us/api/share/7PoDRgCzHFTs2vWB`,得到 +*注意,这里的 `us` 为你创建的账号区域,美国为us,欧盟为eu* ```json { @@ -46,7 +47,7 @@ lang: '' 再接着我们请求,携带请求头 `x-umami-share-token` 值为上一步获得的Token -`https://us.umami.is/api/websites/a66a5fd4-98b0-4108-8606-cb7094f380ac/stats?startAt=0&endAt=1750805999999&unit=hour&timezone=Asia/Hong_Kong&url=/posts/cf-fastip/&compare=false` +`https://cloud.umami.is/analytics/us/api/websites/a66a5fd4-98b0-4108-8606-cb7094f380ac/stats?startAt=0&endAt=1750805999999&unit=hour&timezone=Asia/Hong_Kong&path=eq./posts/cf-fastip/&compare=false` 这里解释几个关键Params,其他的照搬 @@ -54,36 +55,28 @@ lang: '' - endAt:统计结束时间。Unix时间戳,我们可以使用 `Date.now()` ,即当前时间,和startAt参数联动即可实现统计总浏览量 -- url:要查询的路径,填写为你的文章页去除了Host的路径,如 `/posts/hello` 。注意!Umami会将 `/posts/hello` 和 `/posts/hello/` 视为两个不同的路径,请注意你的博客框架是否使用 `/` +- path:要查询的路径,填写为你的文章页去除了Host的路径,如 `/posts/hello` 。注意!Umami会将 `/posts/hello` 和 `/posts/hello/` 视为两个不同的路径,请注意你的博客框架是否使用 `/`。在v3版本中,需要使用 `eq.` 前缀来进行精确匹配,例如 `path=eq./posts/hello/` 你会得到 ```json { - "pageviews": { - "value": 1655, - "prev": 0 - }, - "visitors": { - "value": 343, - "prev": 0 - }, - "visits": { - "value": 411, - "prev": 0 - }, - "bounces": { - "value": 183, - "prev": 0 - }, - "totaltime": { - "value": 30592, - "prev": 0 + "pageviews": 1655, + "visitors": 343, + "visits": 411, + "bounces": 183, + "totaltime": 30592, + "comparison": { + "pageviews": 0, + "visitors": 0, + "visits": 0, + "bounces": 0, + "totaltime": 0 } } ``` -`pageviews.vlaue` 即浏览量。 `visits.value` 即访问次数。 +`pageviews` 即浏览量。 `visitors` 即访问人数。 > Tips:浏览量记录为任意用户只要访问了则计数一次。而访问数记录不会记录单IP多次重复访问和同一时间段的多次请求不同页面