posts: 发布文章:解决困扰我多时的JS重复请求问题

This commit is contained in:
二叉树树
2025-11-18 09:37:05 +08:00
parent 95d078b604
commit d7a84024b8
11 changed files with 51 additions and 6 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 271 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 439 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 250 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -0,0 +1,39 @@
---
title: 解决困扰我多时的JS重复请求问题
published: 2025-11-18T08:46:02
description: 如果你在我的博客初创就关注了,且具有一定的技术能力,你会发现我的博客曾经有一段时间在疯狂魔改,这可能会导致一些问题,并影响至今
image: ../assets/images/swup-js.png
tags:
- Swup
- JS
draft: false
lang: ""
---
# 正式开始
就如封面所说,我的博客是 **魔改** 而来的,而母版为 [saicaca/fuwari: ✨A static blog template built with Astro.](https://github.com/saicaca/fuwari)
就如Fuwari原版所称该项目是一个 **静态博客** 也就是写文章和部署网站是分离的而文章是一个个MarkDown文件构建后输出为HTML
因为原项目一开始就根本没有考虑 **动态功能** 如目前我博客使用的 **访问量显示** ,所以在加入动态功能后可能会有一些问题
这个访问量显示的思路曾在 [该文章](/posts/static-view/) 曾讲述过。我假设你已经看完了那么该思路的步骤有两个1. 首先拿到全局分享Token 2. 拿该Token拿到实际的访问量
当时出现一个奇怪的问题,在步骤一中出现了多次的重复请求。自己分析后发现,我在博客中的三个地方都使用了同一套逻辑,且互相独立。白话来说,就是你打开博客,首先,它会获取全站访问量,同时,由于第一屏已经有一些文章,所以也会同时获取这些文章的访问量
但是这个全局分享Token在极长一段时间内根本不变也就是会有特别多的冗余请求于是当时我写了个中间件将这个Token请求一次后就存到用户的浏览器接下来需要用到的时候直接用无需再次从网络请求中获取
但是在今天,有一位粉丝发现某些页面仍然会多次请求 Umami ,如图
![](../assets/images/swup-js-1.png)
于是,它开了一个 issue [Bug: 站内转跳时由于swup处理不当导致的多umami实例 · Issue #79 · afoim/fuwari](https://github.com/afoim/fuwari/issues/79) 告知我是Swup的问题让Swup不管理这类JS即可设置后的确可用
最终使用该issue的方法后我们随便打开一个页面尝试分析看看是否有问题
![](../assets/images/swup-js-2.png)
我们只看Umami请求
- https://cloud.umami.is/script.js Umami官方的全局JS注入在所有页面中用于后续将访客行为告知给Umami
- http://localhost:4321/js/umami-share.js 之前写的中间件用于避免多次请求Umami拿全局Token
- https://umami.2b2x.cn/analytics/us/api/websites/5d710dbd-3a2e-43e3-a553-97b415090c63/stats?startAt=0&endAt=1763429011353&unit=hour&timezone=Asia%2FShanghai&compare=false :获取全站统计信息。为什么在文章页也会获取全站统计?因为全站统计被安放在用户配置块,而用户配置块全局可见
- https://umami.2b2x.cn/analytics/us/api/websites/5d710dbd-3a2e-43e3-a553-97b415090c63/stats?startAt=0&endAt=1763429243350&unit=hour&timezone=Asia%2FShanghai&path=eq.%2Fposts%2Fswup-js%2F&compare=false :获取本页统计信息
- 两个预检由于CORS请求源和被请求源不一致这是浏览器自带的安全策略实际顺序为 先预检(我不属于你?我能不能访问你?) - 再fetch我允许你访问吧 。题外话:为什么需要预检?因为浏览器要确保该请求是对方明确允许的,而不是恶意网站强行访问的,否则会触发 **CSRF** 攻击也就是对端源安全策略过于宽松导致谁都能拿到信息这些信息可能是敏感的如登录Token用户名与密码等
- https://api-gateway.umami.dev/api/send Umami的官方JS用于将本次访问的行为汇报给Umami
问题已被完美解决!无冗余请求,干净利落

View File

@@ -473,6 +473,12 @@
"avatar": "https://q1.qlogo.cn/g?b=qq&nk=2540797494&s=640",
"description": "让代码更有价值,让学生生活不再枯燥",
"url": "https://blog.yang233.eu.org"
},
{
"name": "zhongzhong's blog",
"avatar": "https://zhongzhong.space/wp-content/uploads/2025/11/avatar.webp",
"description": "小白的半成品拼好站",
"url": "https://zhongzhong.space"
}
]
}

View File

@@ -244,9 +244,9 @@ const bannerOffset =
{/* <!-- Umami分析自建 -->
<script defer src="https://umami.2x.nz/script.js" data-website-id="4b4e430d-a12c-4a5c-8cf9-df48eb20fd6d"></script> */}
<!-- Umami分析云-备用) -->
<script defer src="https://cloud.umami.is/script.js" data-website-id="5d710dbd-3a2e-43e3-a553-97b415090c63"></script>
<script defer src="https://cloud.umami.is/script.js" data-website-id="5d710dbd-3a2e-43e3-a553-97b415090c63" data-swup-ignore-script></script>
<!-- 百度统计 -->
<script>
<script data-swup-ignore-script>
var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
@@ -257,7 +257,7 @@ var _hmt = _hmt || [];
</script>
<!-- clarity 分析 -->
<script type="text/javascript">
<script type="text/javascript" data-swup-ignore-script>
(function(c,l,a,r,i,t,y){
c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};
t=l.createElement(r);t.async=1;t.src="https://www.clarity.ms/tag/"+i;
@@ -266,11 +266,11 @@ var _hmt = _hmt || [];
</script>
<!-- gad -->
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1683686345039700"
crossorigin="anonymous"></script>
crossorigin="anonymous" data-swup-ignore-script></script>
<meta name="google-adsense-account" content="ca-pub-1683686345039700">
<!-- 谷歌分析 -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-9Z4LT4H8KH"></script>
<script async src="https://www.googletagmanager.com/gtag/js?id=G-9Z4LT4H8KH" data-swup-ignore-script></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
@@ -279,7 +279,7 @@ var _hmt = _hmt || [];
gtag('config', 'G-9Z4LT4H8KH');
</script>
<!-- Cloudflare Web Analytics --><script defer src='https://static.cloudflareinsights.com/beacon.min.js' data-cf-beacon='{"token": "15fe148e91b34f10a15652e1a74ab26c"}'></script><!-- End Cloudflare Web Analytics -->
<!-- Cloudflare Web Analytics --><script defer src='https://static.cloudflareinsights.com/beacon.min.js' data-cf-beacon='{"token": "15fe148e91b34f10a15652e1a74ab26c"}' data-swup-ignore-script></script><!-- End Cloudflare Web Analytics -->
</head>
<body class=" min-h-screen transition " class:list={[{"lg:is-home": isHomePage, "enable-banner": enableBanner}]}
data-overlayscrollbars-initialize