司白画博客 - 技术 https://blog.cll.tw/category/%E6%8A%80%E6%9C%AF/ EdgeOne边缘函数实现图片格式转换与缩放 https://blog.cll.tw/archives/edgeone-image.html 2025-08-27T16:33:00+08:00 前言Edgeone 横空出世,不少博客都写上几篇相关的文章,也都用上了免费的服务。虽然 EdgeOne 还不错,但用起来还是没有 Cloudflare 方便,所以我只把静态资源放在了 EdgeOne 加速,包括我的图床(实际上是我的 R2 存储桶)。为了保证原图存储,我的图床在上传之时没有进行图片格式转换和缩放,避免以后需要用到原图时还要重新寻找图片上传。但是过大的图片也实在是考验用户的网速,影响访问体验。EdgeOne 虽然有直接的图片处理服务,但是还要升级个人版,对于一个白嫖用户来说实在是不合适。刚好 EdgeOne 边缘函数 有一定量的免费额度(边缘函数请求数 300万次,边缘函数 CPU Time 300万毫秒),对于我这个小小小图床那是绰绰有余的。EdgeOne 官方文档 提供了示例函数,包含图片自适应 WebP与图片自适应缩放,但是二者并不是合在一起的,或许是为了促进“图片处理服务”的使用吧。如果没有示例函数,对于函数的书写还是有点费劲的,还要把原本那么多文档喂给 ChatGPT。不过现在就很简单了。我们可以借助ChatGPT把两个示例函数进行合并,实现图片自适应转换与缩放,并且不用改变原有图片的链接!这是最为方便的。分函数图片自适应 WebP在文档的最佳实践里面还有一版根据浏览器转换不同格式的,我觉得太过麻烦,所以直接自适应转换 WebP 就好了。async function handleEvent(event) { const { request } = event; // 获取客户端支持的图片类型 const accept = request.headers.get('Accept'); const option = { eo: { image: {} } }; // 检查客户端是否支持 WebP 格式的图片,若不支持响应原图 if (accept && accept.includes('image/webp')) { option.eo.image.format = 'webp'; } const response = await fetch(request, option); return response; } addEventListener('fetch', event => { // 当函数代码抛出未处理的异常时,边缘函数会将此请求转发回源站 event.passThroughOnException(); event.respondWith(handleEvent(event)); });图片自适应缩放经过体验,我感觉图片自适应缩放比单纯的图片质量压缩好,图片自适应缩放可以让质量更小,并且不太影响观感,因为图片的尺寸也更小了。addEventListener('fetch', event => { // 当函数代码抛出未处理的异常时,边缘函数会将此请求转发回源站 event.passThroughOnException(); event.respondWith(handleEvent(event)); }); async function handleEvent(event) { const { request } = event; const urlInfo = new URL(request.url); const userAgent = request.headers.get('user-agent'); // 请求非图片资源 if (!/\.(jpe?g|png)$/.test(urlInfo.pathname)) { return fetch(request); } // 移动端图片宽度 let width = 480; const isPcClient = isPc(userAgent); // PC 端图片宽度 if (isPcClient) { width = 1280; } // 图片缩放 const response = await fetch(request, { eo: { image: { width, } } }); // 设置响应头 response.headers.set('x-ef-client', isPcClient ? 'pc' : 'mobile'); return response; } // 请求客户端类型判断 function isPc(userAgent) { const regex = /(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i; if(regex.test(userAgent)) { return false; } return true; }合函数:图片格式自适应转换与缩放我自然是不会合并的,那就交给 ChatGPT 吧。通过图片格式自适应转换与压缩,一箭双雕,再也不用担心博客图片加载慢的问题了。函数代码addEventListener('fetch', event => { // 当函数代码抛出未处理的异常时,将请求转发回源站 event.passThroughOnException(); event.respondWith(handleEvent(event)); }); async function handleEvent(event) { const { request } = event; const urlInfo = new URL(request.url); const userAgent = request.headers.get('user-agent'); // 请求非图片资源,直接返回 if (!/\.(jpe?g|png)$/i.test(urlInfo.pathname)) { return fetch(request); } // 判断客户端类型 const isPcClient = isPc(userAgent); // 移动端图片宽度 let width = isPcClient ? 1280 : 480; // 获取客户端支持的图片格式 const accept = request.headers.get('Accept'); const imageOptions = {}; if (accept && accept.includes('image/webp')) { imageOptions.format = 'webp'; } // 图片请求 const response = await fetch(request, { eo: { image: { width, ...imageOptions } } }); // 设置响应头 response.headers.set('x-ef-client', isPcClient ? 'pc' : 'mobile'); return response; } // 判断是否为 PC 客户端 function isPc(userAgent) { const regex = /(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i; return !regex.test(userAgent); }功能说明 By ChatGPTPC 客户端宽度 1280,移动端 480。支持 WebP 格式的客户端返回 WebP,否则使用原格式。非图片请求直接返回原始资源。x-ef-client 响应头标识客户端类型。部署函数新建函数规则在 EdgeOne 后台 进入站点,在左侧边栏选择边缘函数,新建一个函数,随意选择一个模版,把函数代码替换成上面的合函数,然后创建并部署。新建触发规则进入刚才创建的那个函数,点击新建触发规则,匹配类型选择HOST,运算符选择等于,值选择为你的图片存储域名,直接确定即可。至于文件后缀限定条件,我觉得可有可无,因为函数本身已经判断过文件是否为图片了。不过如果图片本身有文件后缀,可以再次加上限定条件:png、jpg、jpeg。请不要带上.,否则函数将会无法触发。对于 Gravatar 的镜像站来讲,文件后缀就没有必要限定了,因为 Gravatar 的头像链接是不带文件后缀的,如果限定了文件后缀将会无法转换为 WebP 格式。似乎这个函数代码对于 Gravatar 镜像站无效,可能是因为在函数代码中检测了一次图片类型,所以即使在前端的我触发条件没有限制文件后缀,依然无法转换。对于这个问题,可以使用不进行文件后缀判断的函数代码,并把文件后缀判断的限定移到前端的触发条件中。我们可以对Gravatar 镜像域名单独设定一个触发条件,在前端也不判断文件后缀。// 没有作用,请不要使用 async function handleEvent(event) { const { request } = event; const userAgent = request.headers.get('user-agent'); const isPcClient = isPc(userAgent); let width = isPcClient ? 1280 : 480; const accept = request.headers.get('Accept'); const imageOptions = {}; if (accept && accept.includes('image/webp')) { imageOptions.format = 'webp'; } try { const response = await fetch(request, { eo: { image: { width, ...imageOptions } } }); response.headers.set('x-ef-client', isPcClient ? 'pc' : 'mobile'); return response; } catch (e) { // 如果不是图片或处理失败,返回原始请求 return fetch(request); } }好像怎么改都没用,可是我记得之前的只转换格式代码是可以的。不管了,反正 Gravatar 头像 本身不是很大,转不转换区别不大,开个缓存就好了。测试效果现在来访问部署完函数的站点图片,虽然链接的末尾还是原本的文件后缀,但是打开检查工具,在网络中找到这张图片,就会发现文件类型已经变成了image/webp。再点击一下图片,就会发现图片尺寸变小了,没有原来那么大了,但依然是很清晰的。最后把图片下载下来,发现图片的大小小了很多,并且下载下来的文件后缀为webp。我也来这里放一个测试链接:https://cdn.cll.tw/img/2025/08/1755540774.jpg原本大小为 7.7 MB 的图片,现在已经变为 562 KB 了,加载起来都非常丝滑。参考资料图片自适应 WebP:https://edgeone.ai/zh/document/57423?product=edgedeveloperplatform图片自适应缩放:https://edgeone.ai/zh/document/54770?product=edgedeveloperplatform通过边缘函数实现自适应图片格式转换:https://edgeone.ai/zh/document/54768?product=edgedeveloperplatform结语EdgeOne 也变成大善人了......通过 EdgeOne 边缘函数,可以让图片自适应格式转换与缩放,浏览体验大大提升,也不会影响原图的存储,未来可操作性很强。不过目前博客只有大图片放在了图床上,截图什么的还是存储在本地。虽然有 Typecho 直接上传到兰空图床的插件,但感觉还是存在本地保险。等一会还是迁移一下,双端备份也比较保险呢,速度也能提升一下。截图什么的就不压缩了,清清晰晰的比什么都好。好像有一个问题,自适应图片在第一次访问的时候需要进行转换,所以很慢。但之后就能快起来了呢。还有一个问题就是移动端的缩放太狠了,只考虑了显示大小,却没有考虑放大后的大小。建议将移动端的自适应宽度改为和 PC 端一样。 一键透视不太灵付费资源 https://blog.cll.tw/archives/free-bt0.html 2025-08-26T17:58:00+08:00 前言不太灵曾经是我最喜欢的影视下载站,可是自从它改版之后,所有资源都要会员了,而且还非常贵,我自然是出不起。今天又访问了不太灵看看,发现所谓的付费资源只是被加上了一个遮罩,实际上资源链接已经显示在前台了,我们只需要通过浏览器检查工具去掉遮罩就可以了。VIP的付费弹窗可以直接使用选择工具删除,但是剩下的遮罩如果选择删除,整块区域就会消失,因此需要将这部分的遮罩样式去除。在 ChatGPT 的帮助下,我得出了以下方法。最终效果步骤第一步:删除VIP付费弹窗1. 右键-检查或点击 F12 按键打卡浏览器的检查工具2. 接着点击选择工具,选择 VIP 付费弹窗区域3. 按下你的删除键,VIP 弹窗消失虽然此刻弹窗已经消失,但是遮罩还在,所以我们还需要去除遮罩。但是使用前面这个删除办法已经无法去除遮罩了,而是会让整块区域消失。所以我们需要把遮罩的 CSS 样式给删除,实现透视效果。第二步:删除遮罩 CSS 的样式基本方法:临时去掉样式通过 ChatGPT 的分析,我明白了这个遮罩的本质就是filter: blur(5px); pointer-events: none; user-select: none;。所以我们只需要使用选择工具选择遮罩,在元素树里找到filter: blur(5px); pointer-events: none; user-select: none;这一层,双击选中,删除即可。或者在旁边的样式表中,把这一样式的勾选取消。这时我们就会发现遮罩已经消失,我们就可以直接看到遮罩下的资源了。进阶方法 1:控制台执行 JS 代码一次性去掉遮罩同样的,在检查工具中选择控制台,粘贴以下代码并回车,遮罩也是消失了。document.querySelectorAll("div[style*='blur']").forEach(el => { el.style.filter = "none"; el.style.pointerEvents = "auto"; el.style.userSelect = "auto"; });但是这个方法有点鸡肋,虽然直接使用代码去除遮罩很方便,但依然要执行第一步的删除VIP弹窗,不如也直接临时删除 CSS 样式来得方便。进阶方法 2:写 CSS 覆盖执行方法同上。const style = document.createElement("style"); style.innerHTML = ` [style*="blur"] { filter: none !important; pointer-events: auto !important; user-select: auto !important; } `; document.head.appendChild(style);懒人方法:使用一键书签脚本 (bookmarklet)在浏览器书签栏里添加一个书签,名称随意,链接改为以下代码:javascript:(function(){document.querySelectorAll("div,span,section,article").forEach(el=>{if(el.style.filter&&el.style.filter.includes("blur")){el.style.filter="none";el.style.pointerEvents="auto";el.style.userSelect="auto";}});alert("模糊遮罩已移除");})();在遇到这个遮罩时,只需要点击一下这个书签,遮罩就会消失,很是方便。但同样鸡肋的是,这个书签依然只是去除遮罩,却不能先去除遮罩上面的VIP弹窗,依旧需要手动删除弹窗,方便何在?二合一JS代码既然第二步可以直接使用控制台执行 JS 代码删除,那么第一步也可以,那就可以直接合二为一。第一步的JS删除代码直接让 ChatGPT 搞定。二合一JS代码如下:// 删除 VIP 覆盖层 document.querySelectorAll('.vip-gate-overlay').forEach(el => el.remove()); // 再去掉遮罩样式 document.querySelectorAll("div[style*='blur']").forEach(el => { el.style.filter = "none"; el.style.pointerEvents = "auto"; el.style.userSelect = "auto"; });至于那个浏览器书签脚本,ChatGPT 做出来的好像没有什么用,我也懒得再去调教它了。二合一书签脚本(Bookmarklet)还是调教一下吧,把二合一的JS代码喂给 ChatGPT,再让它输出了二合一书签脚本。使用方法同第二步的书签法,但是只要使用二合一的就可以了。如此一来,只需要点击一下书签,不太灵就会乖乖交出资源了。javascript:(function(){document.querySelectorAll('.vip-gate-overlay').forEach(el=>el.remove());document.querySelectorAll("div[style*='blur']").forEach(el=>{el.style.filter="none";el.style.pointerEvents="auto";el.style.userSelect="auto";});alert("遮罩已移除");})();结语ChatGPT 帮了大忙......不过文字稿都是我自己写滴,只有代码是 ChatGPT 编的,其中不乏我的缝缝补补。就算没有代码可以手动删除遮罩,不失优雅。不太灵虽然加上了VIP可见,但只是加了一个遮罩,并不需要登录了 VIP 才显示,不知道是它的善良还是漏洞。等到不太灵改为检测到VIP才输出资源的时候,这个方法就已经失效了...... Casdoor 实现 OpenList 单点登录 https://blog.cll.tw/archives/casdoor.html 2025-08-25T23:13:00+08:00 前言因为各个站点之间的登录是独立的,一个一个登录很麻烦,况且有一个单点登录系统很酷,于是我之前就很想搞一个。但是奈何这东西有点复杂,于是几番折腾之下我放弃了。最近又看到博友在搞Casdoor,于是我重拾旧本,重新探索,终于在搜索引擎与ChatGPT的帮助之下部署完成。环境1Panel 面板Docker(基于1Panel面板的应用商店)OpenResty(反代服务,大坑!!!)流程1. 在1Panel 应用商店安装 CasdoorCasdoor是一个支持 OAuth 2.0、OIDC、SAML 和 CAS 的 Web UI 优先的 IAM/SSO 平台。2. 在1Panel 网站添加应用 Casdoor即为反代本地8000端口,同时记得配置https证书并解析域名到服务器ip。3. 在 Casdoor 上创建基本信息初始账号为admin,密码为123,进入后台后按照下图进行配置。4. 在 OpenList 上配置单点登录单点登录平台选择OIDC,单点登录端点名称为 Casdoor 的链接,末尾不带/。其他按照上图进行填写。5. 测试登录:错误!就在我满心欢喜地开始使用单点登录时,不幸的事情发生了:{"code":400,"message":"404 Not Found: \u003chtml\u003e\r\n\u003chead\u003e\u003ctitle\u003e404 Not Found\u003c/title\u003e\u003c/head\u003e\r\n\u003cbody\u003e\r\n\u003ccenter\u003e\u003ch1\u003e404 Not Found\u003c/h1\u003e\u003c/center\u003e\r\n\u003chr\u003e\u003ccenter\u003eopenresty\u003c/center\u003e\r\n\u003c/body\u003e\r\n\u003c/html\u003e\r\n","data":null}6. 寻找错误于是我就把这个错误贴给了ChatGPT,它给我的答复是:反代/网关配置问题:你前面有 Nginx/OpenResty 做反代,结果转发的时候找不到后端对应的 location,返回 404。但是ChatGPT给出的解决办法并没有什么用......于是我开始控制变量来验证错误:使用原端口原ip:可以使用反代ip:不可以使用https域名:不可以使用http域名:不可以因此可以得出,问题的确是在OpenResty的反代上。7. 解决反代问题我在搜索引擎上试图寻找遇到相同问题的文章,可惜没有。但是我知道了Casdoor的请求接口是:/.well-known/openid-configuration,因此原来的404问题就出现在这个接口上。我看到这个接口就有点发现问题所在了,中间的一个文件夹为/.well-known,有次域名验证,文件上传到这个文件夹也是404。于是我就把问题丢给了ChatGPT,它给了我解决方案:# 新增 location,放在 ^~ /.well-known 之前 location = /.well-known/openid-configuration { proxy_pass http://127.0.0.1:8000/.well-known/openid-configuration; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; }把这个添加到OpenResty配置文件中,请求接口/.well-known/openid-configuration就可以正常访问了。再次访问OpenList单点登录,登录界面终于可以显示了,但是实际登录却又报错:{"code":400,"message":"failed to verify signature: fetching keys oidc: get keys failed: 404 Not Found \u003chtml\u003e\r\n\u003chead\u003e\u003ctitle\u003e404 Not Found\u003c/title\u003e\u003c/head\u003e\r\n\u003cbody\u003e\r\n\u003ccenter\u003e\u003ch1\u003e404 Not Found\u003c/h1\u003e\u003c/center\u003e\r\n\u003chr\u003e\u003ccenter\u003eopenresty\u003c/center\u003e\r\n\u003c/body\u003e\r\n\u003c/html\u003e\r\n","data":null}于是我又请教了一番ChatGPT,它又给出了解决方案:和之前解决 /openid-configuration 类似,给 /.well-known/jwks 写单独 location:location = /.well-known/jwks { proxy_pass http://127.0.0.1:8000/.well-known/jwks; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; }我再次添加到配置文件中,最后终于登录成功了!!!总结:Casdoor 实现 OpenList 单点登录中,反代问题解决方案:在OpenResty配置文件中加入:# 新增 location,放在 ^~ /.well-known 之前 location = /.well-known/openid-configuration { proxy_pass http://127.0.0.1:8000/.well-known/openid-configuration; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } location = /.well-known/jwks { proxy_pass http://127.0.0.1:8000/.well-known/jwks; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; }参考资料https://doc.oplist.org/guide/advanced/sso#_3-5-casdoor-1https://www.whuanle.cn/archives/21725https://blog.xioxix.com/archives/479结尾折腾了一个晚上总算是把单点登录解决了,幸好有众多大佬的文章与ChatGPT的帮助,最终问题才能解决。但是使用AI解决问题并不是如文中所述一张一帆风顺,而是布满荆棘,解决问题的过程不乏我们的坚持与思考能力。AI的出现不是替代人类,而是帮助人类;人类可以自我选择利用AI且不被AI替代。 不到50元,拿下10年.xyz域名 https://blog.cll.tw/archives/ten-year-xyz.html 2025-08-15T18:52:00+08:00 前几天矫揉造作地注册了一个.com域名,今天就已经无感了,我想明年就不会续费了,这个钱也是浪费了......不过今天又非常想买一个便宜的域名,于是我下手了.xyz的10年域名。概述.xyz本身的价值不高,注册价格也还行,但是续费价格比.com还贵,根本不值得。但但但是,.xyz的6位及以上域名1年只需要4.81元人民币,买十年只需要48.1元,是所有付费域名中最便宜的了。买不了吃亏,买不了上当,人走域还在。购买1. 寻找一个未被注册的域名在WHO.CX上挑选一个未注册的6位数字.xyz,最好是符合你的心意的,比如生日或者某些奇怪寓意的数字。如果被注册了就多换几个。2. 注册域名吧spaceship:https://www.spaceship.com/zh/来到spaceship,基本的注册你肯定都会了,再绑定一下支付宝账号。输入你找到的未被注册的域名,先购买1年(你也无法直接购买多年)。购买成功后再续费9年即可。3. 开始你的旅程吧赶紧打开Cloudflare添加你的域名吧......结语50元不到的10年域名还是很值的,即使当主域名还是不够格,但当一个备用域名还是不错的。 买了一个 .com 域名 https://blog.cll.tw/archives/bought-a-com-domain.html 2025-08-11T17:32:00+08:00 心中一直有一个执念,就是要购买一个com域名。虽然现在这个域名已经很好、很短、很让我满意了,但执念总是挥之不去。于是我还是想要买一个com域名。但是com域名好的、短的都已经被注册了,很难挑选到一个让我满意的。而有的让我满意的却是添加出售,我实在是负担不起。于是我在 Dynadot 二手市场上挑,可是 5、6 个字符的且低价的域名都是随便的字母组合,难以找到与我投缘的域名。因此我决定新注册一个,长的、单词组成的、富有意义的com域名。选哪几个单词呢?两个单词组成的域名基本已经被注册了,所以只能选择 3 个单词的。我想了很久,想出了 FreeSKy,自由天空。出自哪里呢?是《我们的爱》。可是 freessky.com 已经被注册了,那只能加单词了。想来想去,还是加一个 my 比较好,于是成了:myfreesky.com。检查一下,竟然还没有注册过。不过这个域名确实太长了。但我买的欲望还没有那么强。我其实还想注册一个 sibaihua.com,毕竟这个关联性很强,但我又没有那么多钱去注册域名,于是我就在狗爹上域名估值了一下。我最满意的域名竟然只估出了 $789,或许是 tw 这个 TLD 不太值钱。而 myfreesky.com 竟然值 $1863。我想狗爹应该是太过片面的按照 my、free 等关键词进行估价了,又或许是 com 比较值钱呢?sibaihua.com 我看起来很顺心,结果就值 $114,所以我放弃注册这个,等以后发达了再注册。应该不会有人注册这个再来坑我......最后的最后,我注册了 myfreesky.com,但是买了就闲置了。Dynadot 最近有一个活动就是转发 com 域名 有机会获得 500美金,反正现在闲置就先转到我的 YouTube 了。而且 Dynadot 的捆绑销售真是太善良了,原本购买一个 com 需要78元,结果同时购买 com、info、online 只要66元,真是赚大发了。不过这也是 Dynadot 的一个心机,因为 info 和 online 的续费超级贵!千万不要投入生产使用,否则续费时就等着哭吧。所以我反手就挂二手了。其实买域名的最大快乐在于买之前的欣喜和激动,买之后我们看久了也就腻了。 以 ECH 之力对抗 SNI 阻断 https://blog.cll.tw/archives/ech.html 2025-08-08T17:07:00+08:00 引言一个现象:有的域名没有被墙,访问却显示连接已重置。其实,是被SNI阻断了。浏览器通过安全DNS和ECH即可破除SNI阻断,还我互联网。概念介绍抄袭Cloudflare的。安全 DNS传统上,DNS 查询以明文形式发送。任何在互联网上监听的人都能看到您正在连接哪些网站。为了确保您的 DNS 查询保持私密,您应该使用支持安全 DNS 传输的解析器,例如 DNS over HTTPS (DoH) 或 DNSover TLS (DoT)。快速、免费、注重隐私的 1.1.1.1 解析器支持 DNS overTLS(DoT),可以使用支持它的客户端进行配置。在此查看支持的浏览器列表。现在可以按照这些说明在 Firefox 中配置 DNS overHTTPS。两者都可以确保您的 DNS 查询保持私密。ECH加密客户端 Hello (ECH)是 TLS 握手协议的一个扩展,可以防止握手的隐私敏感参数暴露给您和 Cloudflare之间的任何人。这种保护还扩展到服务器名称指示(SNI),否则在建立 TLS 连接时会暴露您要连接的主机名。配置相信你已经懂了这两者的概念,那么如何配置呢。踩坑:阿里云 安全 DNS首先,肯定是要先配置安全 DNS。如何配置?以 Chrome 为例,打开设置 => 隐私与安全 => 使用安全 DNS => 添加自定义服务商:https://223.5.5.5/dns-query理论可行,可是在实际操作时,安全 DNS配置成功了,可ECH却无法开启。网上给的 Chrome 开启 ECH 方法我死活是开不了,Edge 也一样。于是乎我就再去查了查,发现:正确做法:直接使用 Cloudflare 的 安全 DNS设置方法同 阿里云安全 DNS,并且是 Chrome 内置的,设置非常方便。而且我发现,使用 Cloudflare 的 安全 DNS 后,ECH是自动支持的。验证https://www.cloudflare.com/zh-tw/ssl/encrypted-sni/https://tls-ech.dev/https://defo.ie/ech-check.php访问上面任意一个网站即可检查你的浏览器是否支持 ECH 了。小坑验证是否支持 ECH 时请不要使用代理,否则会显示不支持。使用 Cloudflare 的安全 DNS 后访问境内网站速度会变慢,甚至导致代理无法连接,请酌情使用。结语我终于可以直连我的网站了......参考文章https://www.notetoday.net/note/698.htmlhttps://www.v2ex.com/t/1076154https://zhuanlan.zhihu.com/p/3739662610 使用 Cloudflare Pages 部署一个个人主页 https://blog.cll.tw/archives/cloudflare-pages.html 2025-08-07T14:12:00+08:00 导语Cloudflare是一个“终极白嫖平台”,而作为一级域名,如果就给了博客,不免有些浪费。那么,不妨在一级域名上部署一个免费的个人主页吧 ~利用 Cloudflare 的全球网络和算力,让你的个人主页在全球部署!ps:一个静态页面好像也不怎么需要算力......成果展示链接:https://cll.tw几点说明:1. 我把天气的api改为固定的了,所以无论你在哪,都显示“台北市”。为什么呢,因为高德的api免费限制5000个请求,而我又是一个爱网站测速的人。若是给我自己刷爆了就不好玩了。2. 我也把一言api删除了(同样是固定的)为什么呢?因为一言api限制短期请求数,我又爱刷新,于是一直提示一言获取失败,看了很烦,干脆直接固定了。3. 音乐api是我自己搭建的,当然是用 Vercel 一键部署的。因为原本的音乐api好像不能请求了,自己搭建一个也有掌控权。提前准备1. Cloudflare 的后台:https://dash.cloudflare.com/要想使用 Cloudflare Pages 服务,你肯定是要有一个 Cloudflare 账号了。当然,最好在你账号里绑定一个域名,这样子 Pages 就可以使用你自己的域名啦。2. Github 仓库地址:https://github.com/imsyy/home要想用 Cloudflare Pages 搭建一个网站,当然要有网站源码了。而我们要使用的源码,就在这个 Github 仓库里。当然,我对 Github 不是很了解,这里也不用多说了。但是,你首先要有一个 Github 账号呀!搭建1. Fork Github 仓库首先,打开 Github 仓库地址:https://github.com/imsyy/home但这个源码,现在在别人的仓库里,自然不是你的,你又要如何修改呢?所以,先在别人的 Github 仓库里,把仓库给 Fork 下来,就到你的仓库里了。(由于我已经 Fork 过了就不再展示,但是 Fork 键 你肯定知道在哪,对吧!) 很好,被你发现了。所以你一顿操作猛如虎就到你仓库里啦。2. 在 Cloudflare Workers => Workers 和 Pages 里创建 一个 Pages首先,这个 计算 Workers 的入口不是在域名里,而是在Cloudflare控制台的首页 => 右边的边栏里。切换到 Pages 那栏里,点击 导入现有 Git 存储库 的 开始使用。在这里,自然是要授权 Github 账户啦。授权完成后,选择你 Github 的那个存储库,一般来说就是home,然后点击开始设置。3. 设置构建和部署这是非常重要的,因为不知道为什么 Cloudflare 这么傻,不会帮你自动填写 构建命令 和 构建输出目录。当然,框架预设是不用选择的。构建命令:pnpm build 构建输出目录:dist如果你不填这些,Cloudflare 依然会构建成功。可是当你满怀欣喜地打开你的网站,却发现什么都没有,不免落空。4. 将信息变为你的因为这里是 Fork 别人的仓库,信息自然不是我们的。那要如何填入自己的信息呢?其实官方文档已经写得很清楚啦。不过这里还是再点一下吧。1. 主要信息打开你的 Github 仓库,点击根目录下的 .env.example 文件并进入,再点击右上角编辑图标。此时,上方的名称就可以更改啦。自然,是把.env.example重命名为.env,再把相关信息改为你的。最后,点击右上角那个绿绿的键,一顿点击就可以啦。这时,你打开 Cloudflare Pages 的后台,就会发现它正在自动部署啦。如此,你每次在 Github 仓库 所做的更改,Cloudflare 都会察觉并自动帮你部署啦。当然,每次部署都会有一个专属链接,这个链接往往是你的 Pages 域名前再加上一些数字字母。通过这些专属链接,你可以实时查看你的更改,避免缓存的影响。但是在实际使用时,依旧是要用自己的域名啦。2. 其他信息说实话我已经不想再写了,请打开你的 Github 仓库,查看官方的文档把。但是,你要注意,把站点链接和联系方式都改掉哦。注意事项绑定域名在 Cloudflare Pages 的设置里哦。我修改了信息,Cloudflare 也自动部署了,怎么没有变化呢?这是因为缓存,有可能是浏览器的缓存,也可能是 Cloudflare 的缓存。若要立马查看,请使用新部署的专属链接。当然,打开浏览器的无痕模式用你的域名也是可以的啦。结尾天哪写得乱七八糟的,不过应该无人看,很好。如果有不会的当然可以问我啦,说不定我也不会。每次写这种教程类的文章都好累,而且也很难把握的住尺度。究竟是详细一点好还是简单一点好呢?大佬不屑于看,小白又看不懂,嘤嘤嘤。 Wget 爬取 完整的 HTML 网页 https://blog.cll.tw/archives/crawl-html.html 2025-05-31T21:40:00+08:00 缘起今天没事回想起了以前的.tk域名,于是到Dot Tk网站浏览了一番。发现这个网站特别精美,尤其是它的壁纸非常有海岛特色,而且能够随机切换。于是我就想把这个网站给保存下来。可是,如果用浏览器直接保存的话,页面就会有很多元素缺失,且网页也会变成静态的。于是我就询问了一个DeepSeek,得到了使用wget工具爬取html网页的方法。代码wget --mirror --convert-links --adjust-extension --page-requisites --no-parent http://example.com参数说明--mirror: 镜像模式--convert-links: 转换链接为本地可用--adjust-extension: 调整文件扩展名--page-requisites: 下载所有页面资源(CSS、JS、图片等)--no-parent: 不爬取父目录执行方法使用ssh终端连接Linux服务器或使用宝塔面板的终端执行命令。下载完成后会在执行文件夹下生成一个文件夹,即为爬取的网站。 网盘,没有一个好东西 https://blog.cll.tw/archives/bad-netdisk.html 2025-01-25T14:25:00+08:00 起因由于最近日益注重数据的存储,所以准备开始选一家网盘作为年费使用。选择无疑是非常困难的,因为国内各种网盘数不胜数。但实际上又无可选择,因为国内的大部分网盘都和谐得很厉害。但在我心目中和谐最厉害的,还是阿里云盘。阿里和谐王阿里云盘横空出世时,自称不限速。当时以百度网盘为主力的我也入坑了阿里云盘。因为使用得多了,也发现了它的尿性————各种和谐。无论是政治还是黄色,它一律和谐。无论是在资源库还是保险箱中,它一律和谐。而且到现在,它甚至开始了限速。果然,国内的网盘就没有一个可信的。于是我重新回到了百度网盘。百度的怀抱是否温暖?也是和谐王看到了曾经那些珍贵的数据依然存在,我毅然决然地开通了百度网盘的年卡,成为了SVIP2。但是,只有我开始认真使用时,才发现,百度网盘也是一坨。它和谐得跟阿里云盘一样,甚至更加厉害。一切有关政治的书籍全都被封禁了,不过阿里云盘也是这样。但是,压缩包能够幸免一下。然而,你只要手贱双击压缩包,它就会被在线解压,百度网盘就会开始入侵你的压缩包,将你的压缩包一览无余,随后将整个压缩包封禁。我真的会无语。不过,我当然知道它的尿性,重要资料都另用Onedrive存储了一番。至此,百度网盘也成功让我后悔了。我是个很喜欢稳定的人,所以我选择了百度网盘,选择了开年费。但我又是个容易后悔的人。然而,这一切已无法改变。百度网盘也只能勉强备份一下手机图片和日常资料了。那我的年费又有何用呢?云下载,好的幸好,百度网盘的云下载功能还是不错的。虽然有的冷门资源下不下来,但是近期的热门资源都还是OK的。这不就成为我的影视库备选方案了吗。但是,我害怕会员过期,害怕存储爆满。毕竟,百度网盘是要作为我的主力网盘的。所以我只用百度网盘存一些最近要看的电视,或者只有百度网盘有资源的电视。那我想要收藏的影视资源存在哪里呢?变心的115当然是115网盘。虽然业界经常传言115网盘要跑路了,但直到现在,115网盘依然屹立不倒。甚至,它对普通用户也没有丝毫限速。但最令人震惊的,是它不会和谐。是这样的,我存在115网盘上的任何敏感资源都没有被和谐过。还有一个优点就是,它的内存真的非常大。只需要在闲鱼上花十几块就能得到一个15TB左右的账号。这样看来,115网盘简直就是国内的网盘之神。而且,它的会员在暑假时只要115元。那我为什么没有选择115呢,因为,我害怕它跑路。数据的价值是最为重要的。若115跑路了,那么它的一切优点都将失效。还有一点,它的备份功能真的太难用了,或者说,它的APP真的太臃肿了,甚至比百度网盘还卡。这是我无法忍受的。所以,现在115网盘只作为我的影视收藏库。但是,115网盘是我重要的数据底裤。[scode type="blue"]补充一点,115网盘是刀子嘴豆腐心。虽然它在用户协议里说普通用户限速100KB,但是实际上没有限速。不像某些网盘,自称不限速,到后来又开始限速,言行不一,令人可笑。[/scode][scode type="yellow"]2025年3月最新更新:115网盘开始限速250KB了,我的影视存储库计划彻底作废。[/scode]百度,还行回到主题,百度网盘真的那么烂吗?其实不然。作为国内市场占有率第一的网盘,或者说最多人使用的网盘,它跑路的可能性最小,功能最为成熟,是作为养老安家的不二之选。虽然在我未开通百度网盘会员之前,我一见到百度网盘的资源就十分头痛,因为它限速100KB,要下到猴年马月才能下完啊。但是开通会员后,百度网盘的带宽实际上是能跑满的,是能和115网盘的免费版匹敌的。但是,百度网盘在Alist端限速在5MB左右,还是太吝啬了。而且和谐这种东西真的很讨厌,使得我现在重要敏感资料都需要压缩加密后上传。不明攻击对象的升华?网盘变得越来越麻烦,数据使用变得越来越复杂,这一切都是谁害的?不言而喻。 免费SSL看Cloudflare https://blog.cll.tw/archives/free-ssl.html 2025-01-23T14:12:00+08:00 背景Cloudflare作为一家专为白嫖而生的企业大家自然是熟悉。可是要问起来如何正确食用Cloudflare的免费SSL服务时,或许很多人就说不清了。我曾经在互联网上搜过许多教程,但无一是有效的。或许可能是我没有查找到精髓。不过,我想,如今,我已正确掌握了Cloudflare的免费SSL服务食用方法。通过这个方法,你无需在其他网站上再申请SSL证书,也无需通过各种繁琐的域名所有权验证,你只需要把你的域名托管到Cloudflare上即可。相关链接https://dash.cloudflare.com/流程一、将域名托管到Cloudflare这一步相信很多人已经做到了,网上亦有很多教程,这里不再赘述。二、在源服务器上安装Cloudflare的源服务器证书注意,这个源服务器证书不能脱离Cloudflare的服务单独使用,否则浏览器会报不安全提示。(即必须使用Cloudflare的流量代理服务)1.登录Cloudflare后台,选择一个域名,进入你的域名的后台(管理中心)。2.在左侧栏中选择SSL/TLS——源服务器证书,并创建证书。3.在宝塔面板或虚拟主机面板安装该源服务器证书。点击下载键查看该证书的内容及秘钥。请注意保存相关信息。部分信息无法再次查看。打开宝塔面板或虚拟主机面板,分别将内容及秘钥填入框中。[scode type="blue"]不建议在SSL中打开强制https,避免与Cloudflare的功能重复造成网站无法访问。[/scode]这个源服务器证书有效期为15年,但是它不能脱离Cloudflare单独使用。所以就有了接下来的步骤。三、在Cloudflare中配置SSL服务在左侧栏中选择SSL/TLS——概述,将SSL/TLS 加密模式配置为完全。四、大功告成现在,你的网站应该已经能通过https访问了。而实际网页上显示的证书为谷歌诚信所颁发。结语通过Cloudflare所申请的证书,不仅申请方式简单,并且还能自动更新,免去了许多麻烦工作。