2337 字
12 分钟
记录
2026-04-08
一、外部链接跳转提示
1.功能说明
当用户点击新窗口打开的外部链接时,会显示一个确认弹窗,提示用户即将离开本站,确保用户了解他们正在访问的网站。
2.实现位置
- 代码位置:
src/layouts/Layout.astro - 弹窗HTML:在
<head>标签内定义了externalLinkModal弹窗 - JavaScript逻辑:在
<script is:inline>标签内实现了链接点击监听和弹窗显示逻辑
3.禁用方法
方法一:对单个链接禁用
为特定链接添加 data-no-external-prompt 属性:
<a href="https://example.com" target="_blank" data-no-external-prompt>外部链接(无提示)</a>方法二:对整个页面禁用(以下方法选一个就行)
第一种:在单个文件内设置,无需修改全局文件
在页面的 body 标签上添加 no-external-prompt 类:
<body class="no-external-prompt"> <!-- 页面内容 --></body>第二种:方便多个同时设置(实际上非常不实用,能用第一个尽量用第一个,这个就是在第一种方式不行的时候作为备选),需要修改全局文件
步骤 1:修改 Layout.astro 文件中的初始页面加载逻辑
- 操作:打开
src/layouts/Layout.astro文件,找到disableExternalPrompt常量的定义(大约在第40行) - 作用:这一步确保在页面首次加载时,新添加的页面能够正确禁用外部链接跳转提示
- 具体修改:在条件判断中添加新页面的路径,例如:
const disableExternalPrompt = pathname === url("/ym") || pathname === url("/xy") || pathname === url("/about") || pathname === url("/new-page");
步骤 2:修改 Swup 钩子中的页面切换逻辑
- 操作:在同一个文件中,找到
visit:start钩子的定义(大约在第496行) - 作用:这一步确保在用户通过页面导航切换到新添加的页面时,外部链接跳转提示也会被正确禁用
- 具体修改:在条件判断中添加新页面的路径,例如:
if (toPath === url('/ym') || toPath === url('/xy') || toPath === url('/about') || toPath === url('/new-page')) {bodyElement!.classList.add('no-external-prompt');} else {bodyElement!.classList.remove('no-external-prompt');}
关于方法二中的实现方法解释:为什么使用路径检查逻辑
在 src/layouts/Layout.astro 文件中,我们添加了对特定页面路径的检查逻辑,原因如下:
- 全面禁用:虽然我们可以为每个外部链接添加
data-no-external-prompt属性,但这种方法需要手动修改每个链接,容易遗漏。通过在 Layout.astro 中添加路径检查逻辑,我们可以确保这些页面的所有外部链接都自动禁用跳转提示。 - 一致性:这些页面通常包含多个外部链接(如社交媒体链接、个人网站链接等),用户点击这些链接时,通常已经知道他们要访问的是外部网站,因此不需要再显示跳转提示,这样可以提供更一致的用户体验。
- 维护方便:通过集中管理这些页面的外部链接跳转提示设置,后续如果需要添加或修改禁用跳转提示的页面,只需要修改 Layout.astro 文件中的路径检查逻辑即可,不需要逐个修改页面中的链接。
- 页面切换时的处理:我们还在 Swup 的
visit:start钩子中添加了逻辑,确保在页面切换时,body 标签的no-external-prompt类也能正确更新,这样即使用户通过页面导航切换到这些页面,外部链接跳转提示也会被正确禁用。
二、全局人机验证组件
1.组件位置
- 文件位置:
src/components/misc/TurnstileModal.astro
2.功能说明
提供统一的人机验证功能,可在整个博客中调用,用于防止恶意提交和自动化攻击。
3.调用方式
(1) 导入组件
在需要使用人机验证的页面中,首先导入 TurnstileModal 组件:
import TurnstileModal from "../components/misc/TurnstileModal.astro";(2) 添加组件
在页面的合适位置添加组件(通常在页面底部):
<!-- 全局人机验证组件 --><TurnstileModal />(3) 调用验证
在需要验证的地方(例如表单提交前),使用以下代码调用验证:
// 显示人机验证,使用回调函数window.turnstileInstance.show('formName', 'actionName', async function(token) { // 验证成功后的回调函数 // 在这里处理表单提交等逻辑 console.log('人机验证成功,token:', token);
// 示例:提交表单 const formData = { // 表单数据 cfTurnstileResponse: token // 包含验证令牌 };
// 调用API const response = await fetch('/api/endpoint', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(formData) });
// 处理响应...});(4) 参数说明
formName:表单名称,用于标识是哪个表单触发的验证actionName:操作名称,用于 Cloudflare Turnstile 的分析和安全策略callback:验证成功后的回调函数,接收验证令牌作为参数
4.示例:在表单提交时使用
const form = document.getElementById('myForm');if (form) { form.addEventListener('submit', function(e) { e.preventDefault();
// 显示人机验证 window.turnstileInstance.show('myForm', 'form_submit', async function(token) { // 验证成功,提交表单 const formData = new FormData(form); formData.append('cfTurnstileResponse', token);
// 提交表单... }); });}5.环境变量配置
(1)配置步骤
- 登录 Cloudflare 控制台,进入 Pages 项目
- 在 “设置” > “环境变量” 中添加以下变量:
TURNSTILE_SITE_KEY:Cloudflare Turnstile 网站密钥TURNSTILE_SECRET_KEY:Cloudflare Turnstile 秘密密钥SECRET_KEY:用于生成和验证登录令牌的安全密钥
(2)环境变量配置示例
| 环境变量名称 | 类型 | 说明 |
|---|---|---|
TURNSTILE_SITE_KEY | 字符串 | Cloudflare Turnstile 网站密钥 |
TURNSTILE_SECRET_KEY | 字符串 | Cloudflare Turnstile 秘密密钥 |
SECRET_KEY | 字符串 | 用于生成和验证登录令牌的安全密钥 |
(3)代码实现
环境变量获取方式
在 src/utils/auth-utils.ts 文件中,环境变量的获取方式如下:
// 获取环境变量function getEnv(): Env { // 在 Astro 项目中,环境变量可以通过 import.meta.env 获取 if (import.meta && import.meta.env) { return { SECRET_KEY: import.meta.env.SECRET_KEY, TURNSTILE_SITE_KEY: import.meta.env.TURNSTILE_SITE_KEY, TURNSTILE_SECRET_KEY: import.meta.env.TURNSTILE_SECRET_KEY }; } // fallback 到 process.env return { SECRET_KEY: process.env.SECRET_KEY, TURNSTILE_SITE_KEY: process.env.TURNSTILE_SITE_KEY, TURNSTILE_SECRET_KEY: process.env.TURNSTILE_SECRET_KEY };}
const env = getEnv();使用环境变量
// 验证人机验证async function validateTurnstile(response: string): Promise<boolean> { const secretKey = env.TURNSTILE_SECRET_KEY || 'your-turnstile-secret-key'; if (!secretKey) return false;
try { const res = await fetch('https://challenges.cloudflare.com/turnstile/v0/siteverify', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: `secret=${secretKey}&response=${response}` }); const data = await res.json(); return data.success; } catch { return false; }}
// 获取Turnstile站点密钥export function getTurnstileSiteKey(): string { return env.TURNSTILE_SITE_KEY || 'your-turnstile-site-key';}三、数据库配置
1.数据库绑定
- 配置位置:Cloudflare Pages 的环境变量
- 配置步骤:
- 登录 Cloudflare 控制台,进入 Pages 项目
- 在 “设置” > “函数” > “数据库绑定” 中配置
- 绑定名称:
DB - 指向的数据库:
a14797cb-ed36-49d1-ab8e-0aa46afd848c(boke)
2.密钥配置
- Site Key(网站密钥):已硬编码在
src/components/misc/TurnstileModal.astro文件中 - Secret Key(秘密密钥):应在 Cloudflare Pages 的环境变量中配置
- 登录 Cloudflare 控制台,进入 Pages 项目
- 在 “设置” > “环境变量” 中添加
TURNSTILE_SECRET_KEY变量
四、顶置文章方法
1.功能说明
顶置文章是指在博客首页或文章列表中固定显示在最上方的文章,通常用于展示重要信息或公告。
2.实现方法
要顶置一篇文章,只需在文章的 frontmatter 中添加 pinned: true 字段:
---title: 标题published: 2026-03-29description: 介绍image: ""pinned: true---3.注意事项
- 优先级:顶置文章会优先显示在文章列表的最上方
- 多个顶置:如果有多篇文章都设置了
pinned: true,它们会按照发布时间的倒序排列在最上方 - 取消顶置:要取消顶置,只需将
pinned: true改为pinned: false或删除该字段
五、企业微信消息推送
1.功能说明
企业微信消息推送工具,用于向企业微信群机器人发送通知消息,支持文本和 Markdown 格式。
2.环境变量配置
| 环境变量名称 | 类型 | 说明 |
|---|---|---|
WECOM_WEBHOOK_URL | 字符串 | 企业微信机器人 Webhook 地址 |
获取方式:在企业微信群中添加群机器人,复制机器人提供的 Webhook 地址。
3.函数说明
sendWecomMessage(webhookUrl, message)
发送企业微信消息(通用方法)。
参数:
webhookUrl:string - 企业微信机器人 Webhook 地址message:object - 消息对象{msgtype: 'text' | 'markdown' | 'image' | 'news' | 'file' | 'voice' | 'template_card',text: { content: '消息内容' }, // msgtype 为 text 时markdown: { content: '消息内容' }, // msgtype 为 markdown 时// ... 其他消息类型}
返回值:
{ success: boolean, // 是否发送成功 result: any, // 企业微信返回的结果 error?: string // 错误信息(如果有)}sendWecomText(webhookUrl, content)
发送文本消息(便捷方法)。
参数:
webhookUrl:string - 企业微信机器人 Webhook 地址content:string - 文本内容
sendWecomMarkdown(webhookUrl, content)
发送 Markdown 消息(便捷方法)。
参数:
webhookUrl:string - 企业微信机器人 Webhook 地址content:string - Markdown 格式内容
4.调用示例
在 Cloudflare Pages Functions 中调用
// 获取 Webhook 地址const webhookUrl = env.WECOM_WEBHOOK_URL;
if (webhookUrl) { // 发送 Markdown 消息 const message = `**🔔 新赞助待审核**
**昵称:** ${nickname}**金额:** ${amount} 元**订单号:** ${orderId}**赞助日期:** ${sponsorDate}
请管理员及时审核! `.trim();
await sendWecomMarkdown(webhookUrl, message);}发送文本消息
const webhookUrl = env.WECOM_WEBHOOK_URL;
if (webhookUrl) { await sendWecomText(webhookUrl, '这是一条文本消息');}发送 Markdown 消息
const webhookUrl = env.WECOM_WEBHOOK_URL;
if (webhookUrl) { const content = `**标题**
- 列表项1- 列表项2
> 引用文本
[链接](https://example.com) `.trim();
await sendWecomMarkdown(webhookUrl, content);}5.注意事项
- 若未配置
WECOM_WEBHOOK_URL环境变量,推送功能自动禁用 - 企业微信机器人必须已添加到目标群中才能正常接收消息
- Markdown 格式仅支持部分语法,请参考企业微信官方文档