更新日志
发送到 Quickmock 的技术更改 — 功能、修复、安全加固。事实来源(Source-of-truth)是 git 历史记录;此页面是经过整理的面向开发人员的视图。
安全
- 包含控制字符的请求头值将被拒绝。如果 mock 的请求头值含有换行符或其他控制字符(试图夹带额外的请求头),现在会在所有设置请求头的位置——响应头、变体、路由、序列步骤和错误响应——校验失败并给出明确错误。此前这类值在实际响应中已被无害化处理。
- 冒充 LLM API、诱使 AI 代理执行 shell 命令的 mock 将被拦截。反垃圾过滤器现在会拒绝调用 shell 执行类工具的 tool call(OpenAI
tool_calls / function_call、Anthropic tool_use)以及沙箱内的网络侦察。像 get_weather 这样的普通 tool call mock 不受影响。
2026-10-02 — 更精简的内部实现;清除日志会重置计数
已更改
- robots.txt 现在只有一个规则组,不再为 23 个具名爬虫重复相同的规则——所有爬虫(包括 AI 爬虫)获得的访问权限完全不变。
llms.txt 中的指南和模板列表现在与页面和站点地图来自同一注册表生成,不会再过时。
- 创建 mock 的跨站防护现改用 Go 内置的 CSRF 防护。来自其他站点(包括相邻子域名)的浏览器请求会被拒绝;curl、CI 等非浏览器客户端不受影响。语言切换端点只接受自身的表单,不再接受 JSON 请求体。
- 内部清理:约 700 行手写代码被 Go 标准库和数据库驱动取代——API 和 mock 的行为均无变化。
已修复
- 清除 mock 的日志现在也会重置其请求计数。此前日志列表会清空,但摘要仍显示旧的请求数和最后请求时间。
- 对于没有捕获请求的 mock,
GET /api/mocks/:id/logs 现在返回 "logs": [],而不是 null。
- 实时请求检查器从首次访问起即可实时推送。在私有 mock 上,页面会在检查器会话建立之前打开实时连接,被拒绝后悄悄退回到每 2 秒轮询一次服务器;现在会在会话就绪后再连接,锁定状态的检查器也不再轮询。“清除日志”会立即刷新列表,页面每次加载时也不再输出 htmx 错误。
2026-09-26 — 禁止付款请求;修复检查器轮询
安全
- Quickmock 不再托管真实网络上的 x402 付款请求。mock 无法验证付款,因此要求支付真实稳定币的
402 响应对任何付款的代理来说都是陷阱——而且已经有人开始把这类 mock 发布到 x402 发现目录中。现在,创建或编辑带有主网(Base、Ethereum、Solana 等)x402 付款要求的 mock 会返回 422 payment_blocked。测试网(如 base-sepolia)上的 x402 仍然允许,普通的 402 状态码也不受影响。
已修复
- 在已删除或已过期的 mock 上打开的检查器标签页不再无限轮询。请求列表和计数器此前每 2–5 秒请求一次服务器,并默默忽略返回的 404——一个被遗忘的标签页几天内发出了两千多次请求。现在服务器会通知页面停止轮询,页面会提示该 mock 已不存在。
安全
- 源站现在只接受来自 Cloudflare 的网页流量,并且分两个彼此独立的层次:防火墙中只放行 Cloudflare 公布的地址段,由定时器每周刷新;以及 Authenticated Origin Pulls,由 Web 服务器要求 Cloudflare 出示 TLS 客户端证书。正是这一点让访客地址变得可信——Cloudflare 会覆写承载该地址的请求头,但仅对真正经过 Cloudflare 的流量如此。在直连通道尚未关闭之前,任何找到源站的人都可以直接连上来,并声称自己是任意 IP。
已修复
- 每个 IP 的活跃模拟接口上限、速率限制和运营方封禁名单,此前依据的都是一个内部地址而非访客地址,于是三项按 IP 计算的控制被压缩成了一个全局计数器:封禁名单谁也匹配不上,而单个调用方就能耗尽所有人的配额。请求日志里记录的也是同一个毫无用处的地址。现在这些都会解析为真实的客户端 IP。
- 指南长篇章节里的命令此前以普通段落文字呈现——既没有代码样式,也没有复制按钮——可它们恰恰是读者需要照着输入的内容。现在它们与页面上其他代码块外观一致,同样支持一键复制。
已添加
- 相关脚本和完整说明放在仓库的
deploy/cloudflare/ 目录:为什么每一层都必要、按什么顺序启用才不会让站点下线、每周同步如何做到安全失败,以及如果你自己也把服务放在 CDN 后面,有哪些值得知道的坑。
已添加
- 状态过滤:请求检查器现在会捕获每个请求实际服务的HTTP状态,并允许按状态代码过滤日志视图。日志导出包含新字段。
- 语言环境:添加了西班牙语、葡萄牙语和简体中文的完整翻译,使Quickmock能够根据流量趋势为更广泛的全球受众提供服务。
- 公共 API 与命令行工具:执行
go install .../cmd/quickmock@latest 即可获得 quickmock create 命令,它会打印模拟接口的公开 URL 和一次性管理令牌,让 CI 任务无需浏览器就能拿到一次性端点。新的 公共 API 与命令行工具指南介绍了安装方式、各个参数,以及给不想额外安装任何东西的流水线准备的 curl 等价写法。
已修复
- 状态过滤上线时带着三处毛刺,现已打磨平整:状态标记没有定义颜色,500 看上去和 200 一模一样;下拉列表短清单之外的状态会让控件显示全部状态,而下方列表其实已被过滤;日志导出的
?status= 会默默吞掉无效取值,而不像 ?method= 那样返回 422。
- 自托管:本次发布新增的
response_status 列允许为空,导致升级前捕获的请求会让所有日志读取失败。现在该列为 NOT NULL DEFAULT 0,并且新增了一个后续迁移,用于修复已经应用过第一版的实例。
已添加
- 新的
{{mock.url}} 标记可扩展为模拟自身的 base URL — https://quickmock.dev/m/<slug> — 因此响应正文可以指向其自身。这在以前是不可能的:slug 仅在创建模拟后才存在,而模板作者无法提前编写它。
- 新的
{{request.host}} 回显标记返回请求所发送到的 Host。Go 将此值保留在标头映射之外,因此 {{request.header.host}} 无法替代它。
已更改
- 三个模板不再提供你必须手动编辑的占位符。OIDC 发现文档现在通告了可以解析为模拟本身的
issuer、authorization_endpoint、token_endpoint 和 jwks_uri;分页集合的 next 链接是可追踪的;并且problem+json 错误的 instance 指定了一个真实的地址。没有什么是读取 YOUR-SLUG 的了。
已添加
- 三个指南 — 模拟 REST API 端点、测试 Webhook 接收器和测试重试和退避逻辑 — 现在是完整的说明文章,而不仅是带有标题的代码片段:开头有直接的答案,有提出你带来的问题的标题,有一节介绍通常会出错的内容,以及常见问题解答(FAQ)。
- 现在每个模板页面都以对模板用途及有意不做的功能的明确回答开篇,并以指向它所复制的供应商文档或 RFC — Stripe、Slack、GitHub、Shopify、Telegram、RFC 6749、RFC 7517、RFC 9457 — 的链接结束,而不是顺带提及它们。
- 指南和模板页面带有
FAQPage 标记,模板的标记引用了其构建的来源。
已更改
- 指南和模板页面现在会显示它们最后一次更新的时间,并发布与
dateModified 相同的日期。
- 关于重试逻辑和 webhook 接收器的指南增加了关于何时停止重试以及从传递 ID 构建幂等键的章节。
已添加
- 每个指南和模板页面现在都以相关页面的链接结尾,指南链接回基于它构建的模板 — 这两个部分在双向上相互链接,而不仅仅是挂在其索引上。
- 主页直接链接到五个指南和五个模板,而不是仅指向索引。
- 指南、文档和更新日志页面现在带有 schema.org 标记 — 包含发布说明和版本的
ItemList、TechArticle 和 SoftwareApplication。
已更改
- 指南和模板索引页面的标题以它们实际列出的内容为主导,而不是通用的部分名称。
/llms.txt 增加了一个 Documentation 部分,因此 API 参考、OpenAPI 契约和更新日志被分组在 AI 助手寻找它们的地方,而不是放在事实列表的中间。
2026-09-05 — 受信任的客户端 IP 和仅相对重定向
安全
- 每个 IP 模拟限制、IP 黑名单和垃圾邮件过滤白名单背后的客户端 IP 不再从自我报告的
X-Forwarded-For 标头中读取。它现在来自直接反向代理自己的标头(生产环境中的 CF-Connecting-IP),并且仅当该对等方受信任时 — 逗号分隔的伪造将直接被忽略。
- 破坏性变更:模拟的
Location 响应标头现在必须是一个纯相对路径(例如 /m/abc123) — 在主响应、命名变体、路由、序列步骤和错误响应上同样进行检查。绝对 URL、协议相对 //host 和反斜杠变体在创建和更新时被拒绝并返回 422 validation_failed;如果现有行仍然带有此类标头,则在服务时将其丢弃。
- 从
/m/:slug 提供服务的模拟响应现在会发送 Cross-Origin-Resource-Policy: same-origin,因此模拟不再能够作为脚本、图像或 iframe 从其他源加载。模拟本身无法覆盖此标头。
- 内置的反垃圾邮件过滤器增加了用于标志文件读取、携带机密的环境查找、加载器和反向 shell 单行命令、云元数据路径以及两个浏览器劫持习语的模式。
已更改
- 现在,每次修改调用(编辑、删除、扩展以及日志导出或清除)都需要管理令牌 — 即使是在令牌存在之前创建的模拟也没有例外。
2026-08-22 — Go 1.27 和 CI 刷新
已更改
- 后端和生产镜像现在使用 Go 1.27.0 构建;经过完整竞态测试的套件在新的工具链上继续通过。
- GitHub Actions 现在使用与 Node.js 24 兼容的 checkout 和 setup-go 版本,Go 版本直接从
go.mod 获取,以保持 CI 和生产环境一致。
2026-08-19 — 确定性场景、API 工作区和私人日志
已添加
- 命名响应变体现在可以通过
X-Quickmock-Variant 或 __quickmock_variant 明确选择,使确切的边缘情况能够按需重现。
- 有序条件规则使用
equals、not_equals、contains 和 exists 运算符从请求方法、路径、查询、标头或 JSON 正文中选择变体。
- 一个模拟现在最多可以公开 50 个方法和路径路由。将 OpenAPI 3.x JSON 或 YAML 文档粘贴到构建器中以生成工作区路由和示例响应。
- 新的API 文档和机器可读的OpenAPI 3.1 契约涵盖了创建、变体、规则、工作区和检查器隐私。
安全
- 对于新模拟,请求日志默认是私有的。管理令牌可解锁具有路径范围的 HttpOnly 检查器会话;创建者还可以禁用存储请求正文或发送者 IP。
已更改
- SEO/GEO 元数据现在发布互惠的语言站点地图条目,包括文档页面和更新的新鲜度信号,并将模拟、工作区、共享和检查器 URL 标记为不可索引。
2026-08-15 — 抗滥用能力和更安全的模拟响应
安全
- 请求检查器的备用轮询端点现在有自己的每 IP 预算,限制自动突发请求而不影响正常的实时更新。
- 模拟响应不能再扩大 Service Worker 的范围,重定向响应仅接受相对、HTTP 或 HTTPS 目标。
- 内置的滥用过滤器现在拒绝常见的 SSRF 原语、可执行处理程序配置和已知的反向链接页面指纹。自托管用户还可以配置 IP/CIDR 拒绝列表。
已修复
- 容器日志现在默认轮转,并且优雅关闭在排空已关闭队列时不再尝试持久化空请求日志记录。
2026-08-10 — 强化从浏览器创建模拟的功能
安全
- 现在,从站点创建模拟(主页上的表单和模板页面上的一键按钮)如果是由您浏览器中的另一个站点触发的,将被拒绝。脚本访问不受影响:
curl、CI 作业和公共 API 不发送浏览器来源标头,并将继续与以前完全一样工作。
- 这两个相同的操作现在有自己的速率限制预算,与提供模拟流量的预算分开,因此失控的脚本无法消耗您活动模拟的配额。
已更改
- 头部在手机上不再溢出:Templates 部分的链接有六个,一行放不下,因此 GitHub 链接向下移动到页脚中的其他作者链接旁边,其余的导航则换行,而不是跑出屏幕。
- 运行您自己的实例:服务器现在会在启动时警告旧
MOCKAPI_ 前缀遗留的环境变量。自从重命名以来就没有东西读取它们了,所以直到现在一个过时的键都会默默地保留默认值 — 包括新的来源检查依赖的 QUICKMOCK_BASE_URL。
已添加
- 新的/templates部分:涵盖四个类别(支付、开发人员工具、身份验证和身份、通用)的十个现成模拟配置 — Stripe 和 Shopify webhook、GitHub 推送事件、Slack 的
url_verification 握手、OAuth2/OIDC 发现和 JWKS、RFC 9457 错误正文等等。
- 每个模板的“创建此模拟”按钮一键创建它,而“在模拟构建器中打开以首先调整”链接则会在常规模拟表单中打开预先填充的相同配置,以便您可以在保存之前调整字段、标头或状态代码。
- 每个模板页面都会分解有效负载的关键字段,并准确列出模拟与它所模仿的真实服务的不同之处 — 不要假装静态模拟是真正的 API。
已修复
- 主页的“您已达到活动模拟限制”横幅曾经显示请求正文大小限制,而不是实际的模拟计数限制,加上杂乱的
%!(EXTRA int=…) 尾巴。现在它显示正确的数字,没有任何附加内容。
2026-07-26 — TTL 上限、模拟延期、日志导出
已添加
- 模拟的生命周期现在有上限:
ttl_seconds 不能超过 30 天(可由服务器配置),无论是在创建时还是以后设置。
- 模拟页面增加了一个“延期”按钮,将过期时间推迟,从模拟的创建日期起最多可以延长到同样的 30 天上限 — 它需要管理令牌,与编辑或删除模拟一样。
- 响应正文模板增加了四个标记:
{{random.pick:a|b|c}} 每次点击选择一个选项,{{seq}} 计次,加上 {{faker.price}} 和 {{faker.lorem}}。
- 请求检查器可以按 HTTP 方法进行过滤,其“下载 JSON”链接现在导出完整的已捕获请求/响应历史记录(包括发件人 IP) — 与配置导出不同,这需要管理令牌。
已添加
- 创建模拟现在返回一次性管理令牌,在模拟页面上可复制的横幅中显示一次 — 保存它,因为它不能再次显示。
- 编辑模拟、删除它或清除其日志现在需要该令牌:将其作为
Authorization: Bearer <token> 发送。读取模拟、其日志和实时检查器仍然仅通过 slug 工作,不需要令牌。
- 在此版本之前创建的模拟在过期前仍然无需令牌即可工作。新指南:从任何设备管理模拟。
2026-07-05 — 实时检查器、导出和导入、反垃圾邮件
已添加
- 请求检查器通过 Server-Sent Events 流式传输:新请求立即显示,无需轮询,并且页面在 SSE 不可用时会自动退回到轮询。
- 从其页面将模拟的配置导出为 JSON(无日志、无 IP),并在创建表单上导入它 — 从文件或粘贴的文本中,完全在您的浏览器中进行。格式与
POST /api/mocks 匹配,因此导出可以通过 API 重播。
- 反垃圾邮件内容过滤器会阻止滥用性的模拟创建。操作员可以替换内置的模式列表(
QUICKMOCK_SPAM_PATTERNS_FILE),禁用它,或将 IP 设为白名单(QUICKMOCK_SPAM_ALLOW_IPS)。
已添加
- 创建表单上的一个复选框可打开宽松的、无凭据的 CORS 预设(
Access-Control-Allow-Origin: * 等),并使用 204 回答 OPTIONS 预检 — 在任何来源的浏览器 JS 中调用模拟,无需代理。
- 新用例指南:模拟带有 CORS 的 API。
已添加
- 新的/guide部分:针对常见任务的以场景为首的着陆页 — 模拟 REST API、测试重试逻辑、模拟不稳定或缓慢的 API、检查 webhook、返回虚假数据、回显请求。每个页面都有一个随时可运行的 curl 示例;所有这些都在站点地图中列出。
- 每个指南现在在其 curl 示例上都有一个复制按钮,以及一个一键式的创建模拟 CTA,该 CTA 会打开预先填入该配方配置的首页表单 — 方法、正文、延迟、错误率、序列 — 准备好提交。
已添加
- 响应序列:模拟现在可以容纳多达 10 个额外响应的有序列表(每个都有状态 + 正文 + 标头),每次点击循环 — 第一次调用 → 主响应,第二次 → 步骤 2,……然后循环。经典的重试逻辑测试。位置是每个模拟共享的计数器(Redis,具有进程内后备),因此每个调用者都在推进相同的序列。
- 错误率和延迟抖动:可配置比例的请求(0–100%,每个请求掷骰子)可以用备用状态/正文回答,响应延迟可以是一个最小-最大范围用于随机延迟抖动,而不是一个固定值。这三个设置相结合,新的
X-Mockapi-Variant 响应标头(default、error 或 seq-i/n)显示哪个分支提供了每次点击。可从创建表单(新的“不稳定模拟”部分)和 API 配置。
- 主页上的“谁构建了这个”部分现在链接到维护者的个人网站 (deadsquirrel.dev),根据地区匹配语言。
已添加
- 新的
request.* 动态标记将传入的请求回显到响应正文中:{{request.method}}、{{request.path}}、{{request.ip}}、{{request.query.id}}、{{request.header.x-request-id}}、{{request.body}},以及诸如 {{request.body.user.name}} 的 JSON 点路径。值原样插入,不存储任何多余内容 — 静态模拟现在可以用请求本身的数据进行应答。
已修复
- 下面 2026-05-20 的条目过去在每个标记周围显示 Go 模板转义 (
{{`…`}}),而不是标记本身 — 这是从 HTML 模板中复制标记时遗留下来的。现在它显示纯 {{faker.uuid}} 等等。
已添加
已添加
- 这个 /changelog 页面本身,提供英语和俄语版本,带有 hreflang 和
sitemap.xml 中的条目。
- 主页:为在没有上下文的情况下登陆此处的读者提供的一个快速词汇表部分(模拟 API、端点、TTL、Faker 标记、Content-Type)。
- 主页:一个谁构建了这个区块,包含作者简介和到 GitHub、LinkedIn、Telegram 的直接链接 — 以及一个我为什么构建 Quickmock 的个人故事部分,因此该页面不再是一个没有面孔的工具着陆页。
- 主页底部可见的最后更新标记;
dateModified 镜像到 WebApplication JSON-LD 中,以便 AI 爬虫看到新鲜度。
已修复
- URL 中的
?lang=<code> 现在实际上提供该语言。之前规范/hreflang链接指向 ?lang=ru,但解析器只读取 cookie 和 Accept-Language,因此跟踪 hreflang 链接的机器人看到了英文内容 — 多语言信号是个谎言。
安全
- 针对
/m/* 的源加固:公共 mock 路由器现在会剥离可能被恶意调用者用于混淆下游代理的更改请求的标头,slug 被加长(更多的熵),内部错误消息在到达网络之前被脱敏 — 没有 DSN 片段,没有堆栈帧。
- 语言切换器(
POST /language)现在接受同源绝对 Referers,因此在重写 Referer 标头的反向代理后面重定向返回路径可以正常工作。跨源 Referers 仍然被拒绝。
已修复
- RealIP 中间件 现在当直接对等点是环回地址 或 私有/链路本地地址时信任
X-Forwarded-For / X-Real-IP。以前 XFF 仅针对环回对等点受到尊重,因此在 Docker Compose 之后,每个请求都归因于网关(例如 172.18.0.1) — 使得 creator_ip 和 request_ip 毫无用处,并将每个 IP 的 mock 限制变成了全局限制。
- Mock 路由器现在以小写键存储传入的请求标头,因此
request_headers->>'user-agent' 可以正常工作,无论网络大小写如何。
- UI:slug 示例已更新为新的 12 字符格式;mock 详情页面恢复了复制 URL 按钮。
已添加
- 页脚免责声明和使用条款模态框:mock 是用户生成的内容,明确了禁止的类别(恶意软件、网络钓鱼、CSAM、攻击基础设施),并发布了滥用举报渠道。
- 页脚模态框在小视口上保持可用 — 在移动设备上不再裁剪关闭按钮。
已添加
- Faker / now 令牌替换在响应体中:
{{faker.uuid}},{{faker.email}},{{faker.name}},{{now.iso8601}},以及另外 18 个(人物,ID,网络,文本,时间)。mock 按原样存储模板,并在每次命中时呈现新的随机值,因此一个 mock 可以在每次调用中提供不同的数据。完整列表在创建表单的 动态令牌 下。
已修复
- Docker Compose 部署现在等待
--wait 健康检查,而不是在 shell 循环中轮询 /healthz,因此在代理和 Go 进程竞争完成时,部署不再打印表面的 curl: (52) Empty reply。
.env.example 中的 POSTGRES_PASSWORD 示例现在警告不要使用 base64 编码的值 — pgx 的 DSN 解析器会在密码中的 + / = 处崩溃。
已添加
- 核心 mock 引擎:创建、查看、编辑、删除;所有 HTTP 方法,包括
ANY。
- 具有可配置状态、正文、标头、响应延迟(0–30 秒)和 TTL 的公共
/m/:slug 路由器。
- 实时请求检查器:HTMX 2 秒轮询、每个 mock 计数器、清除日志。
- cURL 导入 — 粘贴
curl … 命令以预填充创建表单。
- Mock 详情页上的 JavaScript、Python、Go 和 PHP 代码片段。
- 在
/share/:slug 具有 Open Graph 标签的只读共享预览。
- 每个 IP 的速率限制(8 小时内 5000 次命中)和每个 IP 的活跃 mock 上限(50)。
- 最大响应体 512 KB,由处理程序和 DB
CHECK 约束强制执行。
- Docker Compose 堆栈(应用程序 + Postgres + Redis + 一次性迁移容器)和裸机 systemd 路径。
- EN + RU 本地化、语言切换器(cookie + Accept-Language)。
- 默认注重隐私:没有第三方 JS、没有分析、没有字体 CDN;CI 在每个构建中强制执行此操作。
GitHub 上的完整 git 历史记录 →
← 返回首页