chore: 完善开源项目文档与结构,移除敏感原始图片

- 重写 README.md,添加在线体验、API 文档、部署指南、技术栈等
- 添加 MIT LICENSE
- 添加 CONTRIBUTING.md 贡献指南
- 添加 GitHub Issue/PR 模板
- 完善 .gitignore,防止原始图片和敏感文件误提交
- 从 git 中移除 25 个原始图片文件(.png/.jpg/非序号 webp)
- 项目结构迁移:functions/ -> src/,根目录静态文件 -> public/
- 添加 wrangler.toml 与 package.json 配置
This commit is contained in:
2026-06-06 20:52:59 +08:00
parent f68e19a3bd
commit f45a0068a2
69 changed files with 872 additions and 675 deletions

260
README.md
View File

@@ -1,54 +1,236 @@
# 随机背景API
# RandBG API - 随机背景图片服务
一个可直接部署到 Cloudflare Pages 的静态站点 + Pages Functions API用来按设备方向随机返回背景图。
[![Cloudflare Workers](https://img.shields.io/badge/Cloudflare-Workers-F38020?logo=cloudflare&logoColor=white)](https://workers.cloudflare.com/)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
[![Demo](https://img.shields.io/badge/在线体验-randbg.smyhub.com-28a745)](https://randbg.smyhub.com)
> 一个基于 **Cloudflare Workers** 部署的轻量级随机背景图片 API支持自动识别设备类型移动端/桌面端),并提供优雅的 Web 演示界面。
---
## 在线体验
- **在线演示**: [https://randbg.smyhub.com](https://randbg.smyhub.com)
- **GitHub 仓库**: [https://github.com/shumengya/randbg-api](https://github.com/shumengya/randbg-api)
---
## 特性
- **自动设备识别**:根据 User-Agent 和 Client Hints 自动判断移动端/桌面端
- **双重响应格式**:支持 `302 Redirect` 直接跳转图片,或 `JSON` 返回图片元数据
- **静态资源优化**:使用 WebP 格式,配合 Cloudflare 静态资源缓存,加载极速
- **智能构建流程**`build.py` 自动将原图转换为编号 WebP 并生成 `manifest.json`
- **一体化部署**Worker 负责 API 逻辑,静态页面与图片通过 Assets 提供,单次部署即发布前后端
- **零成本部署**:基于 Cloudflare Workers Free Tier完全免费
---
## API 文档
### `GET /api/random`
随机返回一张背景图片。
| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `mode` | string | `auto` | 强制指定类型:`auto` / `mobile` / `desktop` |
| `orientation` | string | `auto` | 屏幕方向:`portrait` / `landscape` |
| `device` | string | `auto` | 设备类型:`mobile` / `desktop` |
| `format` | string | `redirect` | 响应格式:`redirect`302 跳转)/ `json` |
**示例请求:**
```bash
# 默认 302 跳转到随机图片
curl https://randbg.smyhub.com/api/random
# 返回 JSON
curl https://randbg.smyhub.com/api/random?format=json
# 响应:
# {
# "variant": "desktop",
# "folder": "desketop-image",
# "filename": "7.webp",
# "url": "https://randbg.smyhub.com/desketop-image/7.webp",
# "count": 19
# }
# 强制使用移动端图片
curl https://randbg.smyhub.com/api/random?mode=mobile
# 强制桌面端并返回 JSON
curl https://randbg.smyhub.com/api/random?mode=desktop&format=json
```
### `GET /api/list`
返回各变体的图片清单与统计信息。
```bash
curl https://randbg.smyhub.com/api/list
```
**响应示例:**
```json
{
"generated_at": "2026-05-18T11:45:45.514521+00:00",
"variants": {
"mobile": {
"folder": "mobile-image",
"count": 6,
"images": ["1.webp", "2.webp", "3.webp", "4.webp", "5.webp", "6.webp"]
},
"desktop": {
"folder": "desketop-image",
"count": 19,
"images": ["1.webp", "2.webp", ...]
}
}
}
```
### `GET /manifest.json`
静态清单文件,由 `build.py` 自动生成,记录各变体的目录与文件名列表。
---
## 技术栈
| 层级 | 技术 |
|------|------|
| Runtime | [Cloudflare Workers](https://workers.cloudflare.com/) |
| 静态托管 | Cloudflare Workers Static Assets |
| 构建脚本 | Python 3 + [Pillow](https://pillow.readthedocs.io/) |
| 前端 | Vanilla HTML / CSS / JS |
---
## 项目结构
```
randbg-api/
├── src/
│ ├── worker.js # Workers 入口路由
│ ├── api/
│ │ ├── random.js # /api/random 接口逻辑
│ │ └── list.js # /api/list 接口逻辑
│ └── lib/
│ └── background.js # 通用工具清单加载、设备识别、URL 构建)
├── public/
│ ├── index.html # 演示与文档页面
│ ├── manifest.json # 图片清单build.py 生成)
│ ├── _headers # 静态资源 HTTP 响应头
│ ├── mobile-image/ # 移动端 WebP 图片(构建产物)
│ └── desketop-image/ # 桌面端 WebP 图片(构建产物)
├── mobile-image/ # 原始图片(本地工作目录,不提交到 Git
├── desketop-image/ # 原始图片(本地工作目录,不提交到 Git
├── build.py # 构建脚本:原图 → WebP + manifest.json
├── wrangler.toml # Workers 部署配置
├── package.json # 依赖与脚本
└── README.md # 本文档
```
> **注意**:根目录下的 `mobile-image/` 和 `desketop-image/` 仅用于本地存放原始素材,不应提交到 GitHub。`build.py` 会将转换后的编号 WebP 输出到 `public/` 目录,只有 `public/` 下的内容会被部署。
---
## 部署指南
### 前置条件
- [Cloudflare 账号](https://dash.cloudflare.com/)
- [Node.js](https://nodejs.org/) 18+
- [Python 3](https://python.org/) 3.9+
- [Wrangler CLI](https://developers.cloudflare.com/workers/wrangler/install-and-update/)
### 1. 克隆项目
```bash
git clone https://github.com/shumengya/randbg-api.git
cd randbg-api
```
### 2. 安装依赖
```bash
npm install
```
### 3. 准备图片
将原始图片放入对应目录:
```
mobile-image/ # 竖屏图片(移动端)
desketop-image/ # 横屏图片(桌面端)
```
支持格式:`.jpg` `.jpeg` `.png` `.bmp` `.gif` `.tif` `.tiff` `.webp`
### 4. 构建 WebP 与清单
```bash
python3 build.py
```
脚本会自动完成以下工作:
1. 将原图转换为高质量编号 WebP`1.webp` `2.webp` ...
2. 生成 `public/manifest.json`
3. 将转换后的文件输出到 `public/` 部署目录
如果 `public/` 下已有序号 WebP 且没有原图,脚本会**保留现有文件**,不会误删。
### 5. 本地预览
```bash
npm run dev
```
默认在 `http://localhost:8787` 启动预览。
### 6. 部署到 Cloudflare
```bash
npm run deploy
```
Wrangler 会将 `src/worker.js` 打包为 Worker同时将 `public/` 作为静态 Assets 一起发布。
---
## 目录约定
- `mobile-image/`:竖屏图片原图上传目录
- `desketop-image/`:横屏图片原图上传目录
- **`public/mobile-image/`**:竖屏图片(移动端)
- **`public/desketop-image/`**:横屏图片(桌面端)
- 注意拼写沿用历史目录名API 内部已兼容
- **`public/manifest.json`**构建产物API 运行时通过内部请求读取该清单
## 使用流程
---
1. 把图片上传到对应目录。
2. 运行构建脚本:
```bash
python3 build.py
```
3. 把项目根目录作为 Cloudflare Pages 的发布目录部署。
4. 打开:
- 页面:`/`
- API`/api/random`
## 注意事项
## API
1. **原图不上传**:根目录下的 `mobile-image/``desketop-image/` 仅用于本地构建,已配置 `.gitignore` 避免误提交。GitHub 仓库中只保留构建后的 `public/` 资源。
2. **图片版权**:请确保上传的图片拥有合法使用权或来自版权友好的来源。
3. **Worker 体积限制**:静态资源通过 Cloudflare Assets 提供,不占用 Worker 脚本 4 MiB 限制,可放心使用大量图片。
4. **缓存策略**`public/_headers` 已为图片配置了 `immutable` 长期缓存,为 `manifest.json` 配置了 5 分钟缓存。如需更新图片,请重新运行 `build.py` 并部署。
- `GET /api/random`
- 默认按 `mode=auto` 随机返回图片重定向
- `GET /api/random?format=json`
- 返回 JSON
- `GET /api/list`
- 返回图片清单
---
## 组件嵌入
## 开源协议
```html
<script src="https://random-background-api.pages.dev/widget.js"></script>
<random-background-widget
src="https://random-background-api.pages.dev"
mode="auto"
blur="12"
radius="16px"
height="260px">
</random-background-widget>
```
本项目基于 [MIT License](LICENSE) 开源。
`widget.js` 只读取静态的 `manifest.json` 和图片文件,不会调用 `api/random`。
---
## 构建说明
## 贡献
`build.py` 会把目录里的原图转换成同目录下的编号 `webp` 文件,例如:
欢迎提交 Issue 和 Pull Request如果你有任何建议或发现问题请随时反馈。
- `1.webp`
- `2.webp`
- `55.webp`
---
同时生成 `manifest.json`,供 Pages Functions 读取。
<p align="center">
Made with ❤️ by <a href="https://github.com/shumengya">shumengya</a>
</p>