posts: 添加随机URL生成功能及相关文档和图片资源

添加了随机URL生成功能的实现,包括三种不同技术方案:
1. 传统边缘函数方案
2. Cloudflare规则方案
3. 纯前端JS方案

新增了相关文档说明和示例图片资源,完善了随机URL生成的最佳实践指南
This commit is contained in:
二叉树树
2025-12-29 11:33:54 +08:00
parent 4e57b489de
commit 9f06fa1e9d
14 changed files with 124 additions and 6 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 MiB

View File

@@ -0,0 +1,107 @@
---
title: 完全免费!从架构,开发到部署,一条龙实打实的教你做一言/随机图等随机URL的最佳实践
published: 2025-12-29T10:10:40
description: 我曾于2024搭建了第一个随机图网站最近几周又深度研究了类似项目发现这类项目有很多坑也有很多神秘的捷径并且某些架构还可以做到“永生”...
image: ../assets/images/random-url-gen.png
draft: false
lang: ""
---
# 探索架构
我们先不讲一个抽象的概念,我们首先来做一个小项目
**一个随机图API每次请求都返回不同的图片**
你会怎么做?
有非常多的解决方案就拿最简单的一说我们可以先搞来一个服务器然后往里面塞图片最后写一个脚本创建一个Web服务器接收客户端请求每一个请求都从图片库里抽一张图返回
能实现吗?
当然可以!这是你的流程图!
![](../assets/images/random-url-gen-5.png)
但也会带来一些问题,比如,图片存在本地,给客户端响应图片的时候走的是你机子的流量,那么你就需要一个 **高带宽** 的服务器,这无疑是一个 **高昂** 的成本
那可能你会有新的方案: **前后端分离** 逻辑与资产分离只将返回这个图片的逻辑存放在服务器上而图片存到其他地方如对象存储Cloudflare R2、IPFS等等
![](../assets/images/random-url-gen-6.png)
那么问题又来了,假如说你的项目太多人用了,那你的服务器性能可能不够,在后期,你仍然需要一个 **高昂****维护成本**
那么那么那么,现在是 **2025** 年,传统的架构已经无法满足我们了,我们不妨可以试试 **云函数**
仍然是前后端分离我们现在将逻辑放到一个函数上面如Cloudflare Worker、EdgeOne Function、Vercel Function等等
![](../assets/images/random-url-gen-8.png)
那么现在是不是无敌了?
并非,虽然前端因为使用了 **云函数** 也就是直接接入了CDN高并发已经不是问题了但是由于资产并不直接托管在 **云函数** 中,**云函数** 仍然需要创建一个长连接从你的后端,如对象存储获取图片,这样一折腾,你的服务可能并不算快
有人就会说了,那既然现在我都把我服务器丢了,前端在云,后端也在云,为什么不直接让前端的云直接存储后端的资产呢?
当然可以!你已经非常接近最佳实践了!
绝大部分 **云函数** 都支持动静结合,也就是支持你在他们的云存放一些动态脚本,再顺便 **存放静态资产**
那么接下来,你就得到了一个完全不需要你买服务器托管,也不需要你担心存储爆仓导致天价账单的随机图...了吗?
![](../assets/images/random-url-gen-4.png)
# 探索随机图随机URL的本质
我们刚刚只是在抽象的说明某种架构 **好像** 可行,**好像** 又有什么问题,然后又有一种什么新思路 **好像** 可以解决这个问题
但我们要走的路才刚刚开始我们不妨思考一下随机图又或者说随机URL这类项目服务器如果有究竟发送了什么给客户端客户端又对服务器发回的报文执行了什么动作
你肯定知道如果想要客户端每次请求同一个URL都返回不同的东西那肯定是服务器针对每一个请求都返回了不同的响应它可以是内部的比如直接在响应体塞图片又或者也可以是 **重定向**
直接在响应体塞图片很简单在客户端是不可见的当客户端请求API时服务器直接将选中的图片作为响应体发出在客户端看来就好像是请求了一张图片只不过每次刷新都不一样
而响应 **重定向** 就更简单了,只需要让服务器发送一个 **临时重定向** 的状态码,比如 **302**
有人就会说了,为什么必须要 **临时重定向** ?因为你肯定是想要客户端每次刷新都返回不同的图,一旦你使用了 **永久重定向****301** ,客户端在收到 **301** 的那一刻就会在浏览器里写一个记录:**下次访问这个URL直接重定向不再请求服务器** 这就会导致你的随机图API真的就变成一张图片了
那么,这两种方法哪种更好呢?
各有利弊,一句话说明:**直接返回MIME类型是连请求复用仅需一次请求即可得到图片。而返回302重定向至少需要客户端请求两次**
这得看你的实际架构,如果说你是前后端分离,即逻辑和资产不在一个地方,肯定是 302 好,因为如果你直接在响应体塞图片,就相当于你的服务器作为 **代理** 让客户端访问你的资产,流量全部走你服务器
而如果说你前后端都在一起正常情况下来说一次请求复用肯定是比两次连接更快的不过为了方便管理和统计我的大部分API仍然使用 **302 重定向**
::github{repo="afoim/EdgeOne_Function_PicAPI"}
上线的API https://eopfapi.acofork.com/pic?img=ua
# 奇技淫巧1利用Cloudflare Origin Rules实现无计费的随机URL
> Video: https://www.bilibili.com/video/BV19ZBzB8EDQ/
起因于有一天一位粉丝在我视频下留言
![](../assets/images/random-url-gen-9.png)
他提到的仓库为
::github{repo="Mabbs/cf-hitokoto"}
大致为Cloudflare在规则提供一个方法该方法可以在规则层生成一个UUID而UUID每次都是随机的我们可以依据此来在规则层做随机URL
理论可行,实践开始
首先我们要知道UUID是一串带有连字符的随机数而每一位有16种可能我们可以仅截取前4位也就是 16^4 共能存储65536张图每一张图可以分配到一个唯一的UUID接下来让CF边缘在收到请求的时候生成UUID然后直接拼接URL请求静态资产`/img/0000.jpg` ,再返回给客户端即可
那如果说我图比这多呢加一位16^5 = 1048576够用了吧
那如果说我图比这少呢那我们可以让图片填充说个极端的例子假如你只有2张图每张图创建32768个副本即可依此类推
![](../assets/images/random-url-gen-10.png)
::github{repo="afoim/cf-rule-random-url"}
上线的API https://img.072103.xyz/h | https://img.072103.xyz/v
# 奇技淫巧2丢掉后端让前端JS自己拼URL
> Video: https://www.bilibili.com/video/BV1tNB4BEEaE/
> Video2: https://www.bilibili.com/video/BV1mMBKBREkB/
把思路打开,我们真的需要一个 **请求一个端点,返回一个随机内容** 的东西吗
如果只是想在我们的网站上用上随机图那是不是可以让客户端JavaScript代劳呢
大致原理为编写一个客户端JS生成一个随机数然后拼接URL得到最终的随机图然后寻找需要替换为随机图的img容器或者背景图容器替换其中内容
![](../assets/images/random-url-gen-11.png)
::github{repo="afoim/Static_RandomPicAPI"}
上线: https://pic.acofork.com
# 总结
我们共探索了三种流派
- 传统派:中规中矩,在边缘函数找图,取图
- 极客派通过CF的规则实现在边缘找图取图但是不计费
- 环保派通过客户端JS直接在浏览器上实现找图取图改图

View File

@@ -22,11 +22,7 @@ export function setHue(hue: number, save: boolean = true): void {
if (save) { if (save) {
localStorage.setItem("hue", String(hue)); localStorage.setItem("hue", String(hue));
} }
const r = document.querySelector(":root") as HTMLElement; document.documentElement.style.setProperty("--hue", String(hue));
if (!r) {
return;
}
r.style.setProperty("--hue", String(hue));
} }
export function getRainbowMode(): boolean { export function getRainbowMode(): boolean {
@@ -56,10 +52,25 @@ export function setBgBlur(blur: number): void {
localStorage.setItem("bg-blur", String(blur)); localStorage.setItem("bg-blur", String(blur));
const bgBox = document.getElementById("bg-box"); const bgBox = document.getElementById("bg-box");
if (bgBox) { if (bgBox) {
bgBox.style.setProperty("filter", `blur(${blur}px)`); // Retrieve existing hue-rotate value if any, or 0
const currentFilter = bgBox.style.filter || "";
const hueRotateMatch = currentFilter.match(/hue-rotate\((.*?)deg\)/);
const hueRotate = hueRotateMatch ? hueRotateMatch[1] : "0";
bgBox.style.setProperty("filter", `blur(${blur}px) hue-rotate(${hueRotate}deg)`);
} }
} }
export function setBgHueRotate(hue: number): void {
const bgBox = document.getElementById("bg-box");
if (bgBox) {
// Retrieve existing blur value
const currentFilter = bgBox.style.filter || "";
const blurMatch = currentFilter.match(/blur\((.*?)px\)/);
const blur = blurMatch ? blurMatch[1] : getBgBlur();
bgBox.style.setProperty("filter", `blur(${blur}px) hue-rotate(${hue}deg)`);
}
}
export function applyThemeToDocument(theme: LIGHT_DARK_MODE) { export function applyThemeToDocument(theme: LIGHT_DARK_MODE) {
switch (theme) { switch (theme) {
case LIGHT_MODE: case LIGHT_MODE: