设计归档
设计归档记录 PGSTY SILO 的核心工程决策:缺陷根因、S3 与 IAM 协议不变量、备选方案取舍、运维边界与回归测试索引。
2026-11-10 发布复查中发现
- 生命周期版本历史:同一个版本,两个发行版写的头部(#332):2024-04-28 之前的 MinIO 写入的数据,在纠删集里换过一部分盘之后,生命周期过期为什么会被永久拒绝,以及为什么把两个随写入版本而变的头部字段从修订标识里拿掉就是最小而完整的修复。
2026-11-09 Console 多语言
- 为 SILO 提供多语言支持:随 Console 2.7.0 发布并内嵌于 SILO Server 20261109 的十语言界面(Console 2.6.0 仅含中英文;涵盖 #83 葡语贡献与 silo#277 土耳其语需求),记录维护分级、英文回退与阿拉伯语 RTL,以及支持逐语言分包、全量加载决策的 gzip 和缓存实测。
2026-11-06 发布验收中发现
- 局部视图不能把存在的对象报成不存在(已随 SILO Server 20261109 发布):只能连上部分盘的节点,为什么会对存在的对象返回 404,以及为什么判定“不存在”必须要求每块盘都应答。
- Multipart 提交失败可能让上传卡死(推迟至 SILO Server 20261109 之后):未达到写 quorum 的提交为什么会让上传一直卡到过期清理,以及为什么修复推迟至
SILO Server 20261109之后的版本与存储 RPC fencing 一并交付。
2026-11-04 发布阻塞的生命周期修复
本节所有服务端设计记录对应的修复已随 SILO Server 20261109 发布;Console 配额校验修复已随独立版 Console 2.6.0 与 Console 2.7.0 发布,并内嵌于 SILO Server 20261109。
- 多池生命周期过期:按整个对象决策(#278、#279):解释只按单个池内版本做出的过期判断,为何会隐藏、删除或复活另一个池中的版本,以及为什么在对象锁内按合并版本列表复核是最小而完整的修复。
- 恢复副本:过期的是副本,不是对象(#281、#282):解释当前版本的恢复副本过期为何会隐藏对象或抹掉更早的 null 版本,以及哪些存储层与原生恢复防护要与精确版本修复一起交付。
- 两阶段原生恢复(#284):解释原生恢复为何在整个 tier 下载期间持有对象锁,#281 的第一版防护为何还会让失败的普通上传卡住,以及在锁外暂存、再做一次短暂且经过核验的提交,如何取代私有 upload。
- Peer 重载后的审计 Webhook(#259):解释运行时修改 audit_webhook 为何会让除处理请求的服务器外其他所有服务器上的目标停止工作,哪些日志子系统存在同样问题,以及为什么用服务器上下文构建日志目标、并先打开队列存储是最小而完整的修复。
- 失败写入与幽灵空前缀(#285、#286):解释暂存数据在远端 rename 之前消失的写入,为何会留下空对象目录并在之后被列为空前缀,以及为什么在两条 rename 失败路径上清理它就足够。
- Heal 演练不能删除数据(源自 #280):解释 heal 演练为何会删掉 dangling 对象最后的元数据副本,并在远端节点上执行真实的桶 heal,以及为什么提前返回加上把演练标志传给 peer 能同时关闭这两条路径。
- 生命周期"删除全部版本"只能作用于一个 key(在审查 #278 修复时发现):解释 ExpiredObjectAllVersions、DelMarkerExpiration 和批量过期的默认 purge 为何会删除过期 key 名下的所有其他 key,以及为什么在复核后按版本 ID 只清理该 key 自身的版本,是最小而安全的修复。
- Console 的桶配额:列表显示与数值校验(silo-console#72、silo-console#73):解释 Console 设置的配额为何在桶列表中显示为"-"、创建桶时为何会把超大配额变成 1 字节、两者的来源,以及随独立版 Console 2.6.0 与 Console 2.7.0 发布并内嵌于 SILO Server 20261109 的修复范围。
- 大型单池集群的锁域:解释在 18 台及以上主机的单池集群中,DELETE 与 CopyObject 为何无法与同一 key 上的 PUT 互斥,哪些布局受影响,以及关闭它的路由改动。
2026-11-01 存储池迁移完整性审查
本节所有存储池迁移与分层清理修复已随 SILO Server 20261109 发布。
- 存储池迁移完整性审查:#261、#263 与 #265:维护者对三个问题及其修复的审查,记录 #266 的贡献合并、#276 的维护者后续修复、验证证据与合并顺序。
- 混合 EC 布局与迁移列表(#261、#262):解释一次未完成的降级覆写为何会让可读对象从 decommission/rebalance 列表中消失,以及 #262 为何以最小范围解决问题。
- Tier free version 是内部清理记录(#263、#264):解释 free version 为何必须继续供 healing 使用,但不能作为用户可见的删除标记或迁移版本。
- ILM 过期与存储池迁移顺序(#265、#266、#276):解释版本桶的 Expiration 删除标记为何不能让当前版本被跳过,以及维护者后续修复如何保留 tier 清理和完成语义。
2026-10-24 FULL_OBJECT 校验和复制
- FULL_OBJECT 校验和复制:在初始化上传时保留类型(
#254、#255):解释遗漏类型为何让有效的分片 CRC 对象复制失败,共享请求头的一处修复如何同时恢复已有 CopyObject 路径,以及发送端升级与验收边界。
2026-10-24 多池删除与放置决策
-
多池删除:失败时保住最新副本(
#256、#257):解释在线磁盘预检查为何挡不住执行中的 I/O 故障,分阶段清理如何保住每项的权威副本,以及已合并修复的重试、分层引用、性能和兼容性边界。 -
多池覆盖亲和:为何最终没有采纳 #245(
#245):记录原始放置问题、请求级 quorum 与健康判断改进、仅限普通无版本覆盖的收窄设计、两轮 m3 性能实测,以及小对象覆盖仍未达标后的停止决定。实验修改没有合并。
2026-10-23 Alias 区域
- Alias 区域:小配置改动的兼容性边界:按 alias 保存区域、客户端缓存隔离,以及升级、降级和凭据轮换的边界;已按 mcli 20261109 复核。
2026-10-23 IAM 与 KMS 设计记录
- LDAP 长 DN:恢复登录可用性并守住 IAM 撤销安全边界(
#250):解析NormalizeDN的\xx十六进制转义为何触发对象 IAM 后端的单路径分量 255 字节上限,以及为何仅将物理上无法落盘的纯 ASCII 超长分量归类为errConfigNotFound。 - IAM 策略重载:锁粒度、请求取消与超时预算隔离(
#251):在保留writeMu写串行锁的前提下将慢速策略加载与 KMS 解密移出内存鉴权缓存锁,将取消信号贯通至KES.Decrypt,并将etcd单步读取超时与整批解密预算解耦。
Server 20261018 核心设计记录
围绕 Server 20261018 正式版的核心架构改动,请参阅:
- Object Lock 治理保留期与覆写防护(
SN-2026-015、SN-2026-016) - IAM Admin 凭据授权边界(
SN-2026-017) - 持久化 IAM 撤销与按范围撤销 STS(
SN-2026-013) - LIST 恢复锁开销优化
- ListMultipartUploads 回退决策与容量边界
- 多池对象一致性与迁移保护
- KES 与 OpenBao 集成
-
复制可靠性:删除完成、MRF 可见性与 resync 取消
本文记录随 Server 20260916 交付的三轮复制可靠性修复的问题分析、方案取舍与验收结论: 第一轮(PR #162,合并为 d1105bbb): 修复 #153、#152 与 #137,分别涉及请求入口的操作分类、后台恢复队列的可观测性以及任务取消生命周期。 第二轮(PR #196,提交 0c61128d2): 修复复制工作协程(worker)的删除出口、外层状态聚合与持久化 MRF 标记恢复路径(见第二轮小节)。 第三轮(提交 eb4f5e5b3、254b19ac0 与 …
本文记录随 Server 20260916 交付的三轮复制可靠性修复的问题分析、方案取舍与验收结论: 第一轮(PR #162,合并为 d1105bbb): 修复 #153、#152 与 #137,分别涉及请求入口的操作分类、后台恢复队列的可观测性以及任务取消生命周期。 第二轮(PR #196,提交 0c61128d2): 修复复制工作协程(worker)的删除出口、外层状态聚合与持久化 MRF 标记恢复路径(见第二轮小节)。 第三轮(提交 eb4f5e5b3、254b19ac0 与 …
-
SigV4 签名头覆盖边界:拒绝未签名的 x-amz-* 请求头
本文记录 SILO 的未签名请求头覆盖修复(核心提交 123325430,经 PR #173 合入,安全通告编号 SN-2026-011)以及 PR #177 中的后续签名与载荷校验修复(安全通告编号 SN-2026-012)。上述修复已随 Server 20260916 发布。该漏洞由 Oren Yomtov 报告,并在本地预签名与 Authorization 请求头两条 SigV4 路径上复现。 核心结论(TL;DR) 预签名 PUT URL 可以只对 host 一个请求头签名。此前 …
本文记录 SILO 的未签名请求头覆盖修复(核心提交 123325430,经 PR #173 合入,安全通告编号 SN-2026-011)以及 PR #177 中的后续签名与载荷校验修复(安全通告编号 SN-2026-012)。上述修复已随 Server 20260916 发布。该漏洞由 Oren Yomtov 报告,并在本地预签名与 Authorization 请求头两条 SigV4 路径上复现。 核心结论(TL;DR) 预签名 PUT URL 可以只对 host 一个请求头签名。此前 …
-
SILO Server 20260903 发布前复审
本文记录 SILO 20260903(RELEASE.2026-09-03T13-18-01Z,对应提交 9b11dc9469e650815b775cb47b039610644f5da4,候选复审提交 6e112d1856d4f3655f30fc81ee47e9f43d50d8f3,对比基线 RELEASE.2026-08-06T00-00-00Z 即 3be10fcc1a44f6620ded0bd303461f9d688cca23)的发布前工程复审:第二轮复审发现了哪些遗漏缺陷、修复边界如何收 …
本文记录 SILO 20260903(RELEASE.2026-09-03T13-18-01Z,对应提交 9b11dc9469e650815b775cb47b039610644f5da4,候选复审提交 6e112d1856d4f3655f30fc81ee47e9f43d50d8f3,对比基线 RELEASE.2026-08-06T00-00-00Z 即 3be10fcc1a44f6620ded0bd303461f9d688cca23)的发布前工程复审:第二轮复审发现了哪些遗漏缺陷、修复边界如何收 …
-
鉴权前不做 I/O,Header 不授予权限
本文记录通过 PR #101(提交 938603458 至 04b097fd9)合入 SILO、编号为 SN-2026-008 并随 Server 20260903 发布的 CORS 热路径与复制请求信任边界修复。 概览 两个表面上互不相关的缺陷,实际上源于同一个架构层面的设计失误: 任何携带 Origin 请求头的 HTTP 请求都会促使最外层 CORS 中间件把 URL 第一段路径当成存储桶名称,并在身份认证之前同步从磁盘加载该桶的元数据。 任何携带 …
本文记录通过 PR #101(提交 938603458 至 04b097fd9)合入 SILO、编号为 SN-2026-008 并随 Server 20260903 发布的 CORS 热路径与复制请求信任边界修复。 概览 两个表面上互不相关的缺陷,实际上源于同一个架构层面的设计失误: 任何携带 Origin 请求头的 HTTP 请求都会促使最外层 CORS 中间件把 URL 第一段路径当成存储桶名称,并在身份认证之前同步从磁盘加载该桶的元数据。 任何携带 …
-
ListMultipartUploads 行为契约与设计权衡
本文记录 ListMultipartUploads 在完整工程生命周期中的设计与演进:Server 20261018 当前采用的 MinIO 兼容契约、16 盘纠删集容量压测后于 10 月 18 日执行的部分回滚、10 月 17 日无条件磁盘扫描尝试(#243,合入提交 7e9454456)、9 月 16 日可选 strict 模式(#198),以及 8 月 30 日的原始根因分析。 Server 20261018 当前行为契约 Server 20261018 在 main 分支上恢复了传统的 …
本文记录 ListMultipartUploads 在完整工程生命周期中的设计与演进:Server 20261018 当前采用的 MinIO 兼容契约、16 盘纠删集容量压测后于 10 月 18 日执行的部分回滚、10 月 17 日无条件磁盘扫描尝试(#243,合入提交 7e9454456)、9 月 16 日可选 strict 模式(#198),以及 8 月 30 日的原始根因分析。 Server 20261018 当前行为契约 Server 20261018 在 main 分支上恢复了传统的 …
-
只读 Checksum 审计与可靠的 CLI 输出契约
本文记录 MCLI 只读 checksum 校验工作流,以及发布复核阶段发现的 non-TTY 输出缺陷 pgsty/mc#5 的设计与实现。该命令经由 pgsty/mc 的 pull request #8 与 #13 合入主干,并随 mcli 20260903 正式发布(已内置于 Server 20260903 容器镜像)。 核心概览 历史版本的 CopyObject 实现可能在压缩或加密后的底层存储字节上计算附加校验和(additional checksum),而非在 S3 GET 返回给客 …
本文记录 MCLI 只读 checksum 校验工作流,以及发布复核阶段发现的 non-TTY 输出缺陷 pgsty/mc#5 的设计与实现。该命令经由 pgsty/mc 的 pull request #8 与 #13 合入主干,并随 mcli 20260903 正式发布(已内置于 Server 20260903 容器镜像)。 核心概览 历史版本的 CopyObject 实现可能在压缩或加密后的底层存储字节上计算附加校验和(additional checksum),而非在 S3 GET 返回给客 …
-
两把 SSE-C 密钥,一份 CopyObject 响应
本文记录提交 e73436c99(已随 Server 20260903 发布)中的 CopyObject SSE-C 校验和响应修复。该修复仅作用于目标对象成功提交后的 CopyObject XML 与 HTTP 响应生成阶段;已存储的对象字节、校验和元数据、加密格式、源对象解密、联邦复制与站点复制均保持不变。 概览 一次 SSE-C CopyObject 请求可以同时携带两套相互独立的客户端加密密钥: 角色 请求头 用途 源对象 …
本文记录提交 e73436c99(已随 Server 20260903 发布)中的 CopyObject SSE-C 校验和响应修复。该修复仅作用于目标对象成功提交后的 CopyObject XML 与 HTTP 响应生成阶段;已存储的对象字节、校验和元数据、加密格式、源对象解密、联邦复制与站点复制均保持不变。 概览 一次 SSE-C CopyObject 请求可以同时携带两套相互独立的客户端加密密钥: 角色 请求头 用途 源对象 …
-
配置环境文件不是 Shell 脚本
本文定义 MINIO_CONFIG_ENV_FILE 的启动解析契约,并记录提交 2aea7fe9c(已随 Server 20260903 发布)中的兼容性修复。该文件是 SILO 的专用输入格式;为方便运维而支持可选的 export 前缀,并不意味着它是一段 POSIX shell 脚本。 概览 SILO 支持在启动时从指定文件加载环境变量: export MINIO_CONFIG_ENV_FILE=/etc/default/silo silo server /data 解析器接受如下形式的键 …
本文定义 MINIO_CONFIG_ENV_FILE 的启动解析契约,并记录提交 2aea7fe9c(已随 Server 20260903 发布)中的兼容性修复。该文件是 SILO 的专用输入格式;为方便运维而支持可选的 export 前缀,并不意味着它是一段 POSIX shell 脚本。 概览 SILO 支持在启动时从指定文件加载环境变量: export MINIO_CONFIG_ENV_FILE=/etc/default/silo silo server /data 解析器接受如下形式的键 …
-
BadDigest、InvalidRequest 与 CompleteMultipartUpload 校验和契约
#48 与 #50 的修复已随 Server 20260903 发布,流式校验和后续修复(PR #143)已随 Server 20260916 发布。本文取代八月早期提案中“暂时保留 CRC64NVME 静默规范化”的结论。 20261018:消息文字与提交失败 Server 20261018 包含 #225、#229 与 #238 的消息格式修复:Content-MD5 大小写对齐 S3 规范、PutObject 与 UploadPart 校验失败时显示已知算法名,以及移除 …
#48 与 #50 的修复已随 Server 20260903 发布,流式校验和后续修复(PR #143)已随 Server 20260916 发布。本文取代八月早期提案中“暂时保留 CRC64NVME 静默规范化”的结论。 20261018:消息文字与提交失败 Server 20261018 包含 #225、#229 与 #238 的消息格式修复:Content-MD5 大小写对齐 S3 规范、PutObject 与 UploadPart 校验失败时显示已知算法名,以及移除 …
-
ListObjects 快捷路径不能把不存在的桶伪装成空桶
随 SILO Server 20260903 发布的 PR #37(PR 提交 e9c5340be,合并提交 49c8aeac4,关闭 SILO #32),修复了 ListObjects、ListObjectsV2 与 ListObjectVersions 中三条提前返回(early-return)快捷路径在目标桶不存在时错误返回 HTTP 200 OK 空列表、而非 HTTP 404 NoSuchBucket 的 S3 兼容性回归。 太长不看(TL;DR) 对不存在的桶执行普通 …
随 SILO Server 20260903 发布的 PR #37(PR 提交 e9c5340be,合并提交 49c8aeac4,关闭 SILO #32),修复了 ListObjects、ListObjectsV2 与 ListObjectVersions 中三条提前返回(early-return)快捷路径在目标桶不存在时错误返回 HTTP 200 OK 空列表、而非 HTTP 404 NoSuchBucket 的 S3 兼容性回归。 太长不看(TL;DR) 对不存在的桶执行普通 …
-
一个端点,两种权限:彻底分离用户与组状态
本文记录 上游议题 minio/minio#21478、SILO PR #73(提交 58735ee38 / 2e2377d1c)以及 set-group-status 组状态权限善后提交(229fe2b3c)的鉴权设计与验证记录。上述修复已随 Server 20260903 发布。 太长不看(TL;DR) SILO 同时定义了 admin:EnableUser 与 admin:DisableUser 两项策略权限,但共用的 set-user-status 处理函数过去无论目标状态是什么,都固定 …
本文记录 上游议题 minio/minio#21478、SILO PR #73(提交 58735ee38 / 2e2377d1c)以及 set-group-status 组状态权限善后提交(229fe2b3c)的鉴权设计与验证记录。上述修复已随 Server 20260903 发布。 太长不看(TL;DR) SILO 同时定义了 admin:EnableUser 与 admin:DisableUser 两项策略权限,但共用的 set-user-status 处理函数过去无论目标状态是什么,都固定 …
-
条件 DELETE:一个条件对应一个逻辑对象
单对象条件删除(DeleteObject 上的 If-Match)由 PR #145 引入,随后 PR #178 修复了多池串行化与跨池清理。这两项改动均已随 Server 20260916 发布。 八月围绕 PR #12 的早期方案曾设想更宽的范围——包括批量 DeleteObjects 拒绝保护、额外的 s3:GetObject 读取授权检查,以及“仅比较当前版本”规则——但实际合入的实现并未采纳这些扩展。本文记录 f99ed829b 中已交付的契约,并阐述为什么前置条件判断必须位于单池存储 …
单对象条件删除(DeleteObject 上的 If-Match)由 PR #145 引入,随后 PR #178 修复了多池串行化与跨池清理。这两项改动均已随 Server 20260916 发布。 八月围绕 PR #12 的早期方案曾设想更宽的范围——包括批量 DeleteObjects 拒绝保护、额外的 s3:GetObject 读取授权检查,以及“仅比较当前版本”规则——但实际合入的实现并未采纳这些扩展。本文记录 f99ed829b 中已交付的契约,并阐述为什么前置条件判断必须位于单池存储 …
-
为什么 CompleteMultipartUpload 必须返回 ChecksumType:PR #57 评审记录
Shooks(@Dansyuqri)贡献的 PR #57 修复了 #47,并已随 Server 20260903 发布。当对象保存了附加 S3 校验和时,CompleteMultipartUpload 的 XML 响应现在会一并返回已存储的 ChecksumType 元素。 缺陷与范围 对 @cbornet 报告的 #31 的调查拆出了两个独立缺陷。CRC32 分片上传完成阶段的数据计算路径已由提交 c8590413f 与 3e14733f1 修复。但在分片上传成功完成后,虽然底层对象元数据保存 …
Shooks(@Dansyuqri)贡献的 PR #57 修复了 #47,并已随 Server 20260903 发布。当对象保存了附加 S3 校验和时,CompleteMultipartUpload 的 XML 响应现在会一并返回已存储的 ChecksumType 元素。 缺陷与范围 对 @cbornet 报告的 #31 的调查拆出了两个独立缺陷。CRC32 分片上传完成阶段的数据计算路径已由提交 c8590413f 与 3e14733f1 修复。但在分片上传成功完成后,虽然底层对象元数据保存 …
-
可选校验和,强制失败:修复 UploadPart 与 UploadPartCopy 兼容性
本文记录 SILO #46(合并提交 7fea6d5a5,随 Server 20260903 发布,后续延伸修复见 #63 与 #64)的设计与实现:如何围绕 S3 分片上传的可选校验和请求头,同时理顺分片合并(completion)语义、复制响应、压缩与加密数据流以及兼容性基线守卫。 太长不看(TL;DR) 分片上传(Multipart Upload,简称 MPU)会将大对象切分为多个分片(part)分别上传。AWS S3 允许客户端在上传每个分片时附带校验和(checksum),但将其定义为 …
本文记录 SILO #46(合并提交 7fea6d5a5,随 Server 20260903 发布,后续延伸修复见 #63 与 #64)的设计与实现:如何围绕 S3 分片上传的可选校验和请求头,同时理顺分片合并(completion)语义、复制响应、压缩与加密数据流以及兼容性基线守卫。 太长不看(TL;DR) 分片上传(Multipart Upload,简称 MPU)会将大对象切分为多个分片(part)分别上传。AWS S3 允许客户端在上传每个分片时附带校验和(checksum),但将其定义为 …
-
总量未知时,进度条应该说什么
在 SILO Console v2.1.1 中下载文件夹时,Downloads / Uploads(下载/上传)抽屉会显示 NaN%。尽管后端的流式 ZIP 归档仍在正常传输、底层存储对象也完好无损,但进度条却从“总量未知”错误地跳入了确定进度(determinate)渲染状态——导致运维人员误以为下载已卡死或失败,进而反复点击 Download。 该修复已随 Console 2.2.0(提交 16960f7ab,跟踪议题 #62)发布,并自 Server 20260903(edc8be6ed) …
在 SILO Console v2.1.1 中下载文件夹时,Downloads / Uploads(下载/上传)抽屉会显示 NaN%。尽管后端的流式 ZIP 归档仍在正常传输、底层存储对象也完好无损,但进度条却从“总量未知”错误地跳入了确定进度(determinate)渲染状态——导致运维人员误以为下载已卡死或失败,进而反复点击 Download。 该修复已随 Console 2.2.0(提交 16960f7ab,跟踪议题 #62)发布,并自 Server 20260903(edc8be6ed) …
-
数据库通知统一连接串:#53 的兼容性边界
随 SILO Server 20260903 发布的提交 f1ba68358 修复了 SILO #53,明确了 PostgreSQL 与 MySQL 桶通知目标的兼容性边界、旧配置迁移行为与启动期错误处理契约。 最终决策 SILO 保留 PostgreSQL 与 MySQL 通知目标(notification target),但每种数据库仅支持单一的规范配置键: PostgreSQL 必须提供完整的 connection_string; MySQL 必须提供完整的 dsn_string。 …
随 SILO Server 20260903 发布的提交 f1ba68358 修复了 SILO #53,明确了 PostgreSQL 与 MySQL 桶通知目标的兼容性边界、旧配置迁移行为与启动期错误处理契约。 最终决策 SILO 保留 PostgreSQL 与 MySQL 通知目标(notification target),但每种数据库仅支持单一的规范配置键: PostgreSQL 必须提供完整的 connection_string; MySQL 必须提供完整的 dsn_string。 …
-
只预览文本,绝不执行:SILO Console 文本预览设计
SILO Console 支持预览图片、PDF、音频和视频,但在 v2.1.1 中却无法直接查看日常运维最常检查的小型日志、纯文本、JSON 与 XML 对象。即使对象保存了准确的 Content-Type,前端也会在选择预览渲染器之前将其判定为不支持。 恢复旧版浏览器原生 <iframe> 预览虽然简单,却是错误的修法。存储桶中的对象内容完全由上传者控制;一旦将其作为同源 HTML 或 XML 文档加载,一个便利的预览功能就会退化为同源脚本执行边界。 随 Console 2.2.0 交付的设计 …
SILO Console 支持预览图片、PDF、音频和视频,但在 v2.1.1 中却无法直接查看日常运维最常检查的小型日志、纯文本、JSON 与 XML 对象。即使对象保存了准确的 Content-Type,前端也会在选择预览渲染器之前将其判定为不支持。 恢复旧版浏览器原生 <iframe> 预览虽然简单,却是错误的修法。存储桶中的对象内容完全由上传者控制;一旦将其作为同源 HTML 或 XML 文档加载,一个便利的预览功能就会退化为同源脚本执行边界。 随 Console 2.2.0 交付的设计 …