跳到主要内容

Live 指南 · ARC 2.0.0-beta.32

在 Markdown 中嵌入外部和内部内容

写出受支持的外部或同站 Markdown 嵌入语法,并在本页直接检查渲染出的 frame——源代码与 live 结果同页。

Web Device 会把一小部分独立的 Markdown 链接识别为内容嵌入。这不是把任意网站放进 frame 的通用权限。当前 content reader 识别 YouTube 视频 URL、X/Twitter status URL 与经过校验的同站绝对路径;其他 URL 仍会以可见链接保留。

本页是 feature live 指南。原子 directive 合同见 embed unit。矩阵单行看 unit 页;如何用 + 可运行 frame 看本页。

当 source 本身也是文档的一部分时,使用显式的 embed directive。它能明确表达作者意图,并把 source 直接放在渲染结果上方。

Sample 合同

字段
用途内容 Markdown 中受支持的第三方与同站嵌入
边界不是通用 iframe 能力;对本站内容/AUP state 文档保持只读
作者入口::embed{url=…} 或独立的受识别 URL
表面Web Device document → 带 provider 约束的 frame/media
公共状态YouTube、X status、校验后的内部路径为 released
Fallback / 失败未识别或被拒绝的 URL → 普通链接 / 无 embed descriptor
验证下列路由 · arc --version = 2.0.0-beta.32 · 内部路径仅同站 host

一个 YouTube 嵌入

源代码:

markdown
::embed{url="https://youtu.be/jNQXAC9IVRw"}

渲染结果:

当前 renderer 会把这个受支持的 URL 变成响应式、延迟加载、受 sandbox 约束的第三方 iframe。文档仍是只读的:frame 中不是这个 Markdown 对象的 editor,也不是由文档拥有的 AUP session。只读指本站内容与 AUP state,不代表第三方 frame 不会进行自身的网络行为。

一条 X 帖子

源代码:

markdown
::embed{url="https://x.com/arcblock_io/status/1955367769672950142"}

渲染结果:

renderer 会保留原始 status URL 作为 frame 的 fallback target。嵌入帖子的可用性和外观仍由 X 决定;不要把第三方 frame 当作文档已经持久化状态或授予能力的证据。

一个同站页面或 deck

使用以单个 / 开头的同站绝对路径,嵌入本站的一个页面。客户端 slides widget 初始化完成后,slides 内容对象会以 16 的播放器表面呈现;在此之前,frame 内仍保留它 server-rendered 的文字稿。直接打开 source 路由时,正常的可阅读文字稿仍会保留。

源代码:

markdown
::embed{url="/zh/docs/web-device/slides-demo/"}

渲染结果:

路径必须留在本站内。protocol-relative path、traversal segment、反斜杠与 control character 都会被拒绝;这条 directive 不会授予通用的外部 iframe 能力。query 与 fragment 可以选择目标页面自身支持的状态,例如 deck 的 ?full#slide-… 链接。deck 合同见Markdown Slides

同站 embed 会把目标页放进 iframe。ARC 默认 frame-ancestors 'none' 会拦截这种 framing。要嵌入本站页面,站点必须配置 .web/security

yaml
frame-ancestors: "'self'"

没有它时,iframe 空白,而目标 URL 单独打开仍然正常。本站的 deck 与其它内部 embed 依赖该覆盖。

拒绝路径与普通链接 fallback

当 URL 为空、不是受识别 provider、无法解析、使用非 http(s) scheme,或未通过内部路径检查时,resolveContentEmbed 不返回 descriptor。在内容 Markdown 中这些情况保持为普通链接(或纯文本),而不是 frame。

输入预期结果
受支持的 YouTube / X status HTTPS URLProvider embed frame
..\、control char 的站点路径 /zh/docs/…/同站 internal embed
//evil.example/(protocol-relative)作为内部路径被拒绝 → 无 embed
/../secret 或含 .. 的 path segment拒绝(traversal
含 control character 或 \ 的路径拒绝
https://example.com/not-a-provider无 resolver 匹配 → 普通链接
句子中的内联链接始终保持普通链接

不要为了“证明失败”而在本页把被拒绝路径写成 live ::embed:失败形态是“无 embed”,不是特殊错误外壳。拒绝用例写在上方的 source fence 中,不要做成 live frame。

带上下文的文字保持为链接

只有独立的受支持 URL 或显式 directive 会变成 embed。出现在句子中的链接仍是普通链接:

markdown
继续之前,先阅读[原帖](https://x.com/arcblock_io/status/1955367769672950142)。

渲染结果:

继续之前,先阅读原帖

内容对象和语言版本的精确目录结构见内容对象、元数据与语言;本页记录受识别的外部 provider 与经过校验的同站路径。使用通用 frame 前,先针对它的 target renderer 核验安全与信任边界。

验证证据

基线2026-08-12 · arc --version2.0.0-beta.32
能力行docs/aup/capability-matrix.md (internal, non-routed) · ::embed
实现providers/runtime/web-device/src/content-embed.tsresolveContentEmbedcheckInternalEmbedPath);content-reader.ts embed 分支
站点 framing.web/securityframe-ancestors: "'self'"(同站 iframe)
unit 页embed
公开路由/zh/docs/web-device/markdown-embeds/ · /en/docs/web-device/markdown-embeds/
本地运行arc service start --blocklet blocklets/arcblock --port 4900 · 确认 YouTube 与同站 frame;X 依赖第三方可用性
验收受支持 URL 成 frame(非空白);不受支持保持链接;内部路径仅同站