惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
雷峰网
雷峰网
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Spread Privacy
Spread Privacy
H
Hacker News: Front Page
PCI Perspectives
PCI Perspectives
Webroot Blog
Webroot Blog
罗磊的独立博客
H
Heimdal Security Blog
TaoSecurity Blog
TaoSecurity Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
大猫的无限游戏
大猫的无限游戏
月光博客
月光博客
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Google Online Security Blog
Google Online Security Blog
Last Week in AI
Last Week in AI
美团技术团队
Help Net Security
Help Net Security
The Hacker News
The Hacker News
C
Cisco Blogs
T
The Blog of Author Tim Ferriss
J
Java Code Geeks
The Register - Security
The Register - Security
IT之家
IT之家
WordPress大学
WordPress大学
Jina AI
Jina AI
Recent Commits to openclaw:main
Recent Commits to openclaw:main
H
Help Net Security
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
T
Threat Research - Cisco Blogs
P
Proofpoint News Feed
NISL@THU
NISL@THU
爱范儿
爱范儿
The GitHub Blog
The GitHub Blog
Scott Helme
Scott Helme
V
Vulnerabilities – Threatpost
B
Blog
T
Tenable Blog
博客园 - 三生石上(FineUI控件)
T
The Exploit Database - CXSecurity.com
S
Security Affairs
小众软件
小众软件
Hacker News: Ask HN
Hacker News: Ask HN
Security Latest
Security Latest
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
W
WeLiveSecurity
A
Arctic Wolf
L
LINUX DO - 热门话题
Google DeepMind News
Google DeepMind News
M
MIT News - Artificial intelligence

半方池水半方田

小球称重问题及其引申的思考 蓝色的结构色 病毒是不是生物? 把博客发布交给 GitHub Actions 省外居民身份证的补换领(苏州) hexo-filter-titlebased-link:构建你的数字花园 Vercel 应用实践学习 通过与 Keycloak 配合实现博客文章的受限访问功能 非公开的文章 Soft Mode 非公开的文章 Strict Mode 试试用代码块在 Hexo 中插入实况照片 动态图片测试 Hexo-Butterfly 主题 Preloader 加载页定制 Keycloak 的部署以及 Hexo-Butterfly 网页应用的接入 Authentik 的部署记录 Waline 自建 Auth 认证 记一次行李托运理赔流程(南航) Docker 镜像的制作、拉取与运行 Hexo-Butterfly 主题中对 Algolia 搜索框 Power By 的定制 Hexo 动态加载配置(钩子函数) 设计原则 VSCode 中的配置 Spring AI 中使用 PGVector 实现向量存储 提示词工程速查手册 2025 WePlay 上海两日游 和随机数生成相关的题目 一起撸串(字符串) 树状数组上手了就十分简单 缓存置换算法的实现与 Java 中相关的数据结构 关于海量数据的若干问题 访问者模式填补单分派语言的缺陷 备忘录模式:拍下照片
随机访问文章的实现(Sitemap+本地缓存优化)
wuanqin · 2026-04-08 · via 半方池水半方田

|总字数:855|阅读时长:4分钟|浏览量:|

|出链:0|入链:1

一份古老的代码传承至今,已经有很多的版本…这里介绍我的版本。

随机访问文章的实现思路

随机文章跳转的基本原理就三步:

  • 提前准备好一张站点列表
  • 读取列表,并随机挑一个出来
  • 访问目标地址

站点列表的准备

站点列表可以自己准备,或者使用插件 hexo-generator-sitemap 来生成。

站点列表的样子:

1
2
3
4
5
6
https://blog.uuanqin.top/p/18bbd410/
https://blog.uuanqin.top/p/c7d4d021/
https://blog.uuanqin.top/pages/copyright/index.html
https://blog.uuanqin.top/p/51890a9/
https://blog.uuanqin.top/p/91b7dad/
https://blog.uuanqin.top/pages/about/index.html

优化点

为了保证函数的精简和高效,本文代码有以下优化点:

  • 不重复请求 sitemap.txt,而是利用浏览器本地缓存(带过期)加速网站列表的获取
  • 随机跳转有不依赖任何框架的 CSS 简单提示
  • 随机跳转时将保持 url 参数,如想移除,可自行在REMOVED_PARAMS中填入。

Hexo-Butterfly 主题的使用

这里以菜单栏按钮为例。_config.butterfly.yml 中配置如下:

1
2
3
4
5
6
7
8

menu:
随机: javascript:randomPost(); || iconfont icon-suijibofang

inject:
head:

- <script src="/js/random.js"></script>

random.js 实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91



const RANDOM_CONFIG = {
SITEMAP_URL: '/sitemap.txt',
PATH_FILTER: '/p/',
CACHE_KEY: 'random_post_data',
CACHE_TIME: 24 * 60 * 60 * 1000,
FALLBACK_URL: '/',
REMOVED_PARAMS: []
};

async function randomPost() {

const showNotice = (msg) => {
let snack = document.getElementById('random-snack');
if (!snack) {
snack = document.createElement('div');
snack.id = 'random-snack';

Object.assign(snack.style, {
position: 'fixed', bottom: '30px', left: '50%', transform: 'translateX(-50%)',
backgroundColor: '#333', color: '#fff', padding: '10px 20px', borderRadius: '5px',
zIndex: '9999', fontSize: '14px', transition: 'opacity 0.3s'
});
document.body.appendChild(snack);
}
snack.innerText = msg;
snack.style.opacity = '1';
setTimeout(() => snack.style.opacity = '0', 2000);
};

try {
let urls = [];
const cached = localStorage.getItem(RANDOM_CONFIG.CACHE_KEY);
const now = Date.now();


if (cached) {
const { data, timestamp } = JSON.parse(cached);
if (now - timestamp < RANDOM_CONFIG.CACHE_TIME) urls = data;
}

if (urls.length === 0) {
showNotice('正在同步文章列表…');
const res = await fetch(RANDOM_CONFIG.SITEMAP_URL);
if (!res.ok) throw new Error();
const text = await res.text();

urls = text.split('\n')
.map(l => l.trim())
.filter(l => l !== '')
.map(u => {
try {
let p = new URL(u).pathname;
return p.endsWith('/') ? p : p + '/';
} catch(e) { return null; }
})
.filter(p => p && p.includes(RANDOM_CONFIG.PATH_FILTER));

localStorage.setItem(RANDOM_CONFIG.CACHE_KEY, JSON.stringify({ data: urls, timestamp: now }));
}


const current = window.location.pathname.endsWith('/') ? window.location.pathname : window.location.pathname + '/';
const candidates = urls.filter(p => p !== current);

if (candidates.length === 0) {
showNotice('没有发现其他文章,正在返回主页…');
setTimeout(() => location.href = RANDOM_CONFIG.FALLBACK_URL, 1500);
return;
}

const targetPath = candidates[Math.floor(Math.random() * candidates.length)];


const params = new URLSearchParams(window.location.search);
RANDOM_CONFIG.REMOVED_PARAMS.forEach(p => params.delete(p));

const search = params.toString() ? '?' + params.toString() : '';
const finalUrl = targetPath + search + window.location.hash;

showNotice('正在穿越到随机文章…');
setTimeout(() => location.href = finalUrl, 800);

} catch (err) {
console.error('RandomPost Error:', err);
showNotice('跳转失败,正在返回主页…');
setTimeout(() => location.href = RANDOM_CONFIG.FALLBACK_URL, 1500);
}
}

本文参考

版权声明 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 半方池水半方田

封面生成即梦 AI - 图片 5.0 Lite

Prompt扁平2D卡通插画,「随机文章」封面图,颜色鲜明,元素丰富,主次分明,无文字,包含循环箭头和骰子元素,画面活泼有趣

赞助

  • 微信

    微信

  • 支付宝

    支付宝


avatar

wuanqin

只能懂一点点

最新文章

蓝色的结构色