前言
对我个人来说, 这2个月可以说是令我痛苦的2个月了, 有史以来第一次”挂科”.
30%的原因出在语言上, 这门课需要理解题目并分析. 偏理论, 我缺乏这方面的复习经验.另外40%的原因出在我没有给这门课很高的重视, 我的作业成绩很高, 轻视考试的深度和难度了. 剩下30%的原因是我单打独斗了. 我给这门课程留下的预习复习时间是别的课程的的1/10甚至更少.
遭遇失败也不能找借口, 要找原因, 所以这学期打算找学习伙伴, 并且学习重心放在这门课上.
说起来很轻巧, 实际上在整整1个月的假期中 (12.13考完-12.27出这门课的成绩-1.13开学)情绪低落了大半个月, 什么都没有做, 也什么都没有做好. 仿佛回到了本科时候被论文和考研压得喘不过气的日子. 做梦惊醒, 呼吸费劲成为常态… 然后养成了现在每天吃维生素D的习惯.
苦中得乐
谢谢亲人和好友, 在我低落的时候开导我安慰我, 让我不至于一蹶不振. 和好友一起在家吃火锅, 打雪仗, 打游戏. 让我的情绪稳定了很多.
去IGA买了三文鱼, 自己在冰箱冻了半个月来杀死寄生虫. 基于售卖的三文鱼的样子, 我得出了一个结论, 国内的三文鱼都是达不到生食品质的, 均为冷冻杀死寄生虫后再拿出来售卖的, 自己冻会更便宜和健康.

还有最大的一个改变就是驾驶技术, 飞速增长. Montreal迈入冬季, 一周可能有6天都没有太阳, 在体感温度大约为-15℃的天气还是开车出门购物更合适. 偶尔接上朋友去购物, 经常要跑高速. 争取这学期考下来驾照.
博客装修
从上年年底友邻竹子在Mastodon转发了OpenHeart相关的帖子后我尝试部署了一下. 出现了无法使用的问题, 近日仔细查找后发现提供的worker.js
多了一次编码, 导致前端GET和POST的地址和KV中所存储的不一样. 在这里提供一些参考性的建议.
Openheart整个流程为: 前端传递-后端存储-前端获取. 当在前端点赞后, 通过脚本(worker.js)创建键值对(KV)进行存储, 并通过前端js来刷新显示最新的点赞计数. 现在来详细的进行部署.
后端存储
本文教程使用Astro和Cloudflare
首先创建一个存储库: 存储和数据库-KV-创建. 如果想开箱即用, 名字就和我一样设置为KV
即可.
接下来创建Cloudflare Workers, 代码为:
const instruction = `.^⋁^.'. .' \`OpenHeart protocol API`;
export default { async fetch(request, env) { if (request.method === 'OPTIONS') { return new Response(null, { headers }); } if (request.method === 'GET') { if (url(request).pathname === '/') { return new Response(instruction, { headers }); } else { return handleGet(request, env); } } if (request.method === 'POST') return handlePost(request, env); },};
const headers = { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Methods": "GET,POST", "Access-Control-Max-Age": "86400",};
function error(text, code = 400) { return new Response(text, { headers, status: code });}
function url(request) { return new URL(request.url);}
function ensureEmoji(emoji) { const segments = Array.from( new Intl.Segmenter({ granularity: 'grapheme' }).segment(emoji.trim()) ); const parsedEmoji = segments.length > 0 ? segments[0].segment : null;
if (/\p{Emoji}/u.test(parsedEmoji)) return parsedEmoji;}
// Generate KV keys with single encodingfunction generateKey(domain, uid, emoji) { const encodedDomain = encodeURIComponent(domain); // Single encoding const encodedUid = encodeURIComponent(uid); // Single encoding return `${encodedDomain}:${encodedUid}:${emoji}`;}
async function handleGet(request, env) { const [domain, ...uidParts] = url(request).pathname.slice(1).split('/'); const decodedDomain = decodeURIComponent(domain); // 解码 const decodedUid = decodeURIComponent(uidParts.join('/')); // 解码 const prefix = `${encodeURIComponent(decodedDomain)}:${encodeURIComponent(decodedUid)}`; // 单次编码 console.log("GET Prefix:", prefix); // 调试日志
const res = await env.KV.list({ prefix }); const list = {}; for (const key of res.keys) { const value = await env.KV.get(key.name); const [, uidDecoded, emoji] = key.name.split(':').map(decodeURIComponent); // 解码键值 const obj = list[uidDecoded] || {}; obj[emoji] = Number(value); list[uidDecoded] = obj; }
console.log("GET Response Data:", list); // 调试日志 return new Response( JSON.stringify(list[decodedUid] || {}), { headers: { ...headers, 'Content-Type': 'application/json;charset=UTF-8' } } );}
async function handlePost(request, env) { const urlObject = url(request); const path = urlObject.pathname.slice(1); if (path === '') return error('pathname missing');
const [domain, ...uidParts] = path.split('/'); const decodedDomain = decodeURIComponent(domain); // 解码 const decodedUid = decodeURIComponent(uidParts.join('/')); // 解码 const emoji = ensureEmoji(await request.text()); if (!emoji) return error('request body should contain an emoji');
// Generate the key with single encoding const key = generateKey(decodedDomain, decodedUid, emoji); console.log("POST Generated Key:", key); // 调试日志
const currentCount = Number(await env.KV.get(key) || 0); await env.KV.put(key, currentCount + 1);
return new Response('recorded', { headers });}
在推送后回到Worker的设置界面, 绑定刚刚创建的KV, 名称均设置为KV.
当我使用自定义域的时候出现了问题, 因此我使用了默认的workers.dev域名.
前端传递/获取
接下来就是前端的传递. 在Openheart的协议中, 你需要在访问API时提供一个target和uid, 这个target可以是任何字符串, 于是我设置为当前博文的链接并将uid默认为like
.
所以根据官方的文档, 可以通过以下命令来进行POST(点赞)和GET(获取点赞数)操作:
curl -d '💯' -X POST 'https://xxx.workers.dev/xxx.example.com/like'recorded%curl 'https://xxx.workers.dev/xxx.example.com/like'{"❤️":1}%
在这个过程中, 特殊字符, 例如:/
会根据worker.js设置来影响对KV的存储. 因此需要对url编码一次来转换这些特殊字符.
---// Get current URL dynamicallyconst currentUrl = Astro.url.toString();---<div class="like"><open-heart href={`https://xxx.workers.dev/${currentUrl}/like`} data-umami-event="Like" emoji="❤️">❤️</open-heart></div>
这样的请求和存储就保持一致了, 你可以通过开发者工具来确认这一点
最后就是前端样式, 由于我的基于benji的二次修改, 这是benji的文章链接, 可以自行访问获取.
书影音游
颓废的这段时间都用来看小说了, 重新看了一遍龙族.
第七集的抽帧让我感到惊艳, 就是最后的结尾略显仓促, 杰斯陪葬的动机我感觉不是很清晰.
圣诞时候和大家一起用Switch玩了.
一部不错的魔幻史诗, 在刚出的时候觉得名字好听体验了一下, 被冗长的任务打断了. 现在创新号重新回坑过完了剧情, 很棒.