# [萌芽妙妙工具]RandBG API：一个零成本、可自托管的随机背景图片API

> **开源地址**:  [github.com/shumengya/randbg-api](https://github.com/shumengya/randbg-api)  
> **开源协议**:  [MIT License](https://github.com/shumengya/randbg-api/blob/main/LICENSE)  
> **在线体验**:  [randbg.smyhub.com](https://randbg.smyhub.com)
> **作者**: *树萌芽*

---

## 前言

平时写博客、做落地页，总需要随机背景图。用别人的服务怕挂、怕限速；自己搭又嫌重。我想要一个**够轻、够快、够便宜**的方案——最好不用维护服务器，直接部署就能跑。

Cloudflare Workers 的 Free Tier 每月 10 万次请求，对个人项目完全够用。问题是：图片放哪儿？

直接把图片塞进 Worker 脚本？不行，Worker 有 4 MiB 体积限制，几十张图直接撑爆。

所以我把架构拆成两层：Worker 只跑 API 逻辑，图片和前端页面全部走 **Workers Static Assets**。

---

## 项目架构

```
┌─────────────┐     ┌──────────────────┐     ┌──────────────┐
│   用户请求   │────▶│ Cloudflare Worker│────▶│ Static Assets│
│             │     │   /api/random    │     │  WebP 图片   │
└─────────────┘     └──────────────────┘     └──────────────┘
```

**Worker 端**：不到 200 行 JS，只做三件事——读 `manifest.json`、识别设备、302 或 JSON 响应。

**静态端**：`public/` 目录下放 `index.html`、`manifest.json`、编号 WebP 图片。`wrangler deploy` 一次把前后端一起发布。

这样做的好处很直接：
- Worker 脚本极小，冷启动几乎无感
- 图片走 Cloudflare CDN，全球缓存
- 不涉及数据库，无状态，不存在宕机

---

## 核心功能

### 设备识别

根据 `User-Agent` 和 `Sec-CH-UA-Mobile` 自动判断移动端/桌面端，返回对应方向的图片。你也可以手动指定：

```bash
curl https://randbg.smyhub.com/api/random?mode=mobile
```

### 响应格式

默认 `302 Redirect` 直接跳转到图片地址，浏览器里一行就能用：

```html
<img src="https://randbg.smyhub.com/api/random" />
```

加上 `?format=json` 返回元数据，方便前端自己控制加载逻辑：

```json
{
  "variant": "desktop",
  "folder": "desketop-image",
  "filename": "7.webp",
  "url": "https://randbg.smyhub.com/desketop-image/7.webp",
  "count": 19
}
```

### 构建流程

写了个 `build.py`，功能单一但够用：

1. 扫描 `mobile-image/` 和 `desketop-image/` 目录
2. 用 Pillow 把原图转为编号 WebP（`1.webp`、`2.webp`...）
3. 输出到 `public/` 并生成 `manifest.json`
4. 如果已有 WebP 且没有原图，自动保留，不会误删

```bash
python3 build.py
npm run deploy
```

---

## 部署

整个部署流程是：

1. 把原图扔进 `mobile-image/` 和 `desketop-image/`
2. `python3 build.py` 转 WebP
3. `npm run deploy` 推到 Cloudflare

从改图到上线，本地测试用 `npm run dev`，本地 8787 端口就能跑。没有 Docker，没有数据库，没有环境变量要填。

---

如果你也需要一个零成本、不用维护的随机背景服务，可以直接 Fork 用。代码量很小，改起来不费劲。
