# UDID获取 **Repository Path**: baozouboy/udid ## Basic Information - **Project Name**: UDID获取 - **Description**: iOS/iPadOS 设备 UDID 一键获取服务:通过描述文件(mobileconfig)回调收集设备信息,支持多语言、结果页与轮询回跳。PHP 零依赖。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-28 - **Last Updated**: 2026-09-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # UDID 获取 · EdgeOne Pages Functions 版 复刻 [udid.ipadump.com](https://udid.ipadump.com) 的「网页读 iOS 设备 UDID」功能, 移植为 **EdgeOne Pages Functions(边缘函数 + KV)** 纯静态动态站。 推送到 Gitee 后由 EdgeOne 自动构建部署,`git push` 即上线,无需任何自有服务器。 --- ## 工作原理 1. 用户在 iOS 的 Safari 里点「获取 UDID」→ 访问首页。 2. 首页通过 `/api/begin`(或 `/begin`)建一条记录,下发一个 `.mobileconfig` 描述文件。 3. iOS 安装描述文件时,会把 `UDID / 设备名 / 机型 / 系统版本 / 序列号` 等 以 XML plist 的形式 POST 回本站的回调地址(`/receive/{token}`)。 4. 本站落盘后 302 跳到结果页(`/r/{token}`),前端轮询 `/api/check` 拿到结果并展示。 > ⚠️ iOS 只接受 **HTTPS** 下发的描述文件(HTTP 能装,但回调永不来)。部署后必须用 HTTPS 域名访问。 --- ## 目录结构 ``` . ├── functions/ │ └── [[default]].js # Pages Functions 入口(catch-all,接管所有非静态路径) ├── src/ # 函数逻辑(被打包进边缘运行时) │ ├── config.js # 配置(默认值 + 环境变量覆盖) │ ├── storage.js # 存储层:KV(生产)/ 内存(兜底) │ ├── plist.js # plist XML 编解码(递归下降,无 DOMParser 依赖) │ ├── profile.js # 生成 .mobileconfig │ ├── device.js # 设备字段规整 + 机型名映射 │ ├── i18n.js # 20 语言协商 │ ├── http.js # 请求解析 / 响应构造 │ ├── qr.js # 纯 JS 二维码(无第三方依赖) │ ├── views.js # 页面 HTML 渲染(类名与 style.css 严格对应) │ └── helpers.js # UA / 转义等小工具 ├── lang/ # 20 个语言包(*.js,export default 对象) ├── static/ # 纯静态资源(由 EdgeOne CDN 直接服务) │ ├── css/style.css │ └── js/main.js ├── favicon.svg # 静态图标(CDN 直接服务) ├── tests/edge-e2e.mjs # 本地端到端冒烟测试 ├── legacy/ # 原 PHP 版(参考资料,不参与部署) └── package.json ``` 静态资源(`static/`、`favicon.svg`)由 EdgeOne CDN 优先服务,**不会**进入函数; `functions/[[default]].js` 是兜底路由,命中所有未被静态文件接管的路径(含 `/`)。 --- ## 部署步骤 1. **代码托管**:把本仓库推到 Gitee(EdgeOne 支持从 Git 仓库直接拉取部署)。 2. **新建 / 选择 EdgeOne Pages 项目**,框架选「EdgeOne Pages Functions」。 函数目录**必须是 `functions/`**(官方 Pages Functions 约定,见 [Pages Functions 文档](https://edgeone.ai/document/162227908241616896))。 ⚠️ 不能改名成 `edge-functions/` 之类 —— 那是 Makers 产品的约定,Pages 不识别, 函数不会注册,全站 404(踩过一次)。 3. **开启 KV 存储**(控制台 → KV 存储 → 申请 → 建命名空间)。 4. **绑定 KV 到项目,并指定「变量名」为 `udid_kv`**。 > 变量名必须是 `udid_kv`。`src/storage.js` 通过全局变量 `globalThis.udid_kv` 访问 KV; > 名字不对会导致找不到 KV,函数退化为「内存存储」,记录无法跨边缘节点/请求存活。 5. **部署分支**指向你 push 的分支(默认 `master`),保存后自动构建上线。 ### 可选环境变量(不配则用默认值) | 变量 | 含义 | 默认 | |---|---|---| | `ORIGIN` | 站点对外地址(留空则按请求 URL 自动推断) | 空 | | `BRAND` | 站点主标题 | `UDID 获取` | | `BRAND_SUB` | 副标题 | `Apple UDID 查询服务` | | `ORGANIZATION` | 描述文件里的组织名 | `UDID 获取` | | `IDENTIFIER_PREFIX` | 描述文件 PayloadIdentifier 前缀 | `com.example.udid` | | `WEB_CLIP` | 是否生成「结果页」桌面快捷方式 | `1` | | `WEB_CLIP_LABEL` | 快捷方式名称 | `我的 UDID` | | `LEGACY_BAIT` | 是否提供旧版 iOS 触发文件 | `1` | | `BAIT_DELAY_MS` | 触发延迟(毫秒) | `3000` | | `DEVICE_ATTRIBUTES` | 向设备索取的字段(逗号分隔) | `UDID,IMEI,MEID,ICCID,VERSION,PRODUCT,SERIAL` | | `TTL_DAYS` | 记录过期天数 | `7` | | `RETENTION_DAYS` | 隐私页展示的保留天数 | `7` | | `CONTACT` | 隐私联系方式 | 空 | | `DEBUG` | 出错时是否暴露堆栈 | `0` | --- ## 端点一览 | 方法 | 路径 | 说明 | |---|---|---| | GET | `/` `/{locale}` | 首页(按 cookie / Accept-Language 选语言) | | GET | `/{locale}/help` `/{locale}/privacy` `/help` `/privacy` | 帮助 / 隐私页 | | GET | `/begin` | 建记录 → 302 到描述文件(无 JS 也能走通) | | GET | `/install/{token}.mobileconfig` | 下发描述文件 | | GET | `/provision-bait.mobileprovision` | 旧版 iOS 触发文件 | | POST | `/receive/{token}` | iOS 回调,解析设备信息 → 302 结果页 | | GET | `/r/{token}` | 结果页 | | POST | `/api/begin` | 前端建记录(返回 token / 各地址) | | POST | `/api/check` | 轮询:描述文件装好了没 | | POST | `/api/forget` | 删除自己的记录 | | GET | `/qr.svg` | 二维码(仅本站地址) | | GET | `/healthz` | 健康检查 | 支持 20 种语言:`zh(简中) zh-tw(繁中) en ja ko de fr es pt it nl pl ru tr ar hi bn id th vi`。 --- ## 与原始 PHP 版的差异 - **运行环境**:PHP(需服务器) → 边缘函数(V8,无 `fs`/`path`/`Buffer`,无 PKCS#7 签名能力)。 - **存储**:本地 JSON 文件 → EdgeOne KV(全局变量 `udid_kv`,跨请求/节点持久化)。 - **描述文件签名**:原版若未配证书也是「未签名」状态。边缘运行时无法做 OpenSSL PKCS#7 签名, 因此本版**一律下发未签名描述文件**——iOS 仍会安装,仅提示「未签名 / 未验证」,功能不受影响。 如需去掉该提示,需自备 Apple 企业级签名证书(本项目不含签名逻辑)。 - **代码组织**:为贴合边缘运行时,模块全部为纯 ESM(无 npm 依赖、无 Node 内置模块), 语言包从 `lang/*.json` 改为 `lang/*.js`(`export default`)以避免 JSON import 属性的兼容性差异。 --- ## 本地测试 无需部署,用 Node 22 直接跑端到端冒烟测试(同进程内复用内存存储,模拟「同一边缘节点」): ```bash node tests/edge-e2e.mjs ``` 覆盖:首页/多语言/帮助隐私页、建记录、描述文件下发、模拟 iOS 回调、轮询、结果页、 二维码、健康检查、删除记录、404 等,全部通过为 43 项。 --- ## 安全与隐私 - 每条记录用 32 位十六进制随机 token 作为地址,不可猜。 - 设备信息仅用于当次展示,默认 7 天后过期(KV 侧按写入时 TTL 计)。 - 不记录可定位到个人的额外信息(IP 默认不记,需显式开启)。