AEM SDI整理

发布于:2026-07-08 Adobe AEM 0条评论


AEM 使用 Sling Dynamic Include (SDI) 来实现基于 Sling 的 SSI 机制,它可以根据 Web 服务器、CDN 或代理服务器的能力动态选择 SSI(Server-Side Includes)或 ESI(Edge-Side Includes)。

AEM 通过 SDI(Sling Dynamic Include)判断是否将组件转换为 SSI,主要依据 resource-typespath,两者同时满足时,SDI 才会自动将组件内容转换为 SSI 语法。


1. Sling Dynamic Include (SDI) 的作用

AEM DispatcherCDN 之间,SDI 允许动态内容(如 Experience Fragments、页眉页脚)被替换为 SSI 或 ESI 指令,以便 后端 Web 服务器或 CDN 进行解析,而不是直接由 AEM 进行渲染。这可以提升缓存效率,同时确保部分内容始终是动态的。

SDI 的核心逻辑

  1. AEM 解析页面,但不会直接渲染指定组件
  2. SDI 插件替换这些组件为相应的 SSI/ESI 指令
  3. Web 服务器(如 Apache/Nginx)或 CDN(如 Akamai)解析这些指令
  4. 最终用户请求页面时,服务器会动态填充这些组件

2. 解析SDI 配置

{
  "include-filter.config.enabled": true,
  "include-filter.config.path": "/content/experience-fragments",
  "include-filter.config.resource-types": [
    "lenovo-www/components/content/flashfooter",
    "lenovo-www/components/content/flashheader",
    "lenovo-base/components/content/flashfooter/v1/flashfooter",
    "lenovo-base/components/content/flashfooter/v1/flashheader"
  ],
  "include-filter.config.extension": "html",
  "include-filter.config.include-type": "$[env:SDI_INCLUDE_TYPE;default: ESI]",
  "include-filter.config.add_comment": "$[env:SDI_INCLUDE_COMMENT;default: false]",
  "include-filter.config.ttl": "",
  "include-filter.config.required_header": "Server-Agent=Communique-Dispatcher",
  "include-filter.config.ignoreUrlParams": [],
  "include-filter.config.rewrite": true
}

关键配置项解析

配置项作用
"include-filter.config.enabled": true启用 SDI 插件
"include-filter.config.path": "/content/experience-fragments"只对 /content/experience-fragments 下的内容启用 SDI
"include-filter.config.resource-types": [...]只对这些 组件类型 启用 SDI,例如 flashfooterflashheader
"include-filter.config.extension": "html"只对 HTML 页面生效
"include-filter.config.include-type": "$[env:SDI_INCLUDE_TYPE;default: ESI]"默认使用 ESI(如果 Web 服务器支持 SSI,也可以切换到 SSI)
"include-filter.config.add_comment": "$[env:SDI_INCLUDE_COMMENT;default: false]"是否在 HTML 代码中插入 SDI 处理的注释(默认关闭)
"include-filter.config.selector": "$[env:SDI_INCLUDE_SELECTOR;default: nocache]"默认情况下源码中是nocache
"include-filter.config.ttl": ""该项为空,意味着由缓存机制控制 TTL
"include-filter.config.required_header": "Server-Agent=Communique-Dispatcher"Dispatcher 代理的请求才会启用 SDI(避免本地开发时影响)
"include-filter.config.rewrite": true允许对 include 语句进行 URL 重写

3. SDI 处理的 HTML 输出

AEM 直接渲染 的情况下,组件的 HTML 可能是:

<div class="flash-footer">...</div>

但在 SDI 处理 后,AEM 不会直接渲染内容,而是输出 ESI/SSI 指令,例如:

如果使用 ESI(默认)

<esi:include src="/content/experience-fragments/global-footer.html"/>

这样 CDN(如 Akamai) 会解析并插入 global-footer.html 的内容。

如果使用 SSI

如果 include-type 设为 SSI,AEM 可能输出:

<!--#include virtual="/content/experience-fragments/global-footer.html" -->

这样 Web 服务器(如 Apache/Nginx) 会解析这个指令。


4. 如何修改 SDI 以支持 SSI

你的配置默认是 ESI,但如果你想改成 SSI(让 Apache/Nginx 处理),可以调整:

"include-filter.config.include-type": "SSI"

然后,在 AEM 页面 HTML 源码中,你会看到:

<!--#include virtual="/content/experience-fragments/global-footer.html" -->

这时,Dispatcher 需要启用 mod_include(前面提到的 Apache 配置)。


5. SDI 在 AEM 中的典型应用场景

  • 优化 Dispatcher 缓存
    • 让整个页面缓存,但让某些部分动态加载
  • CDN 动态渲染
    • 通过 ESI 让 CDN 直接处理 Experience Fragments
  • 减少 AEM 服务器压力
    • 让 Web 服务器解析 SSI,而不是让 AEM 反复生成相同内容

6. AEM SDI 判断 SSI 逻辑

SDI 主要依赖于 两个核心条件

  1. 组件的 resource-typeinclude-filter.config.resource-types 列表中
  2. 组件所在的路径符合 include-filter.config.path 规则

页面渲染时,SDI 过滤器会检查组件

  • 如果 resource-typepath 都匹配
    • SDI 拦截组件的 HTML 输出
    • 组件的 HTML 替换为 SSI 语法
    • 页面最终渲染出 <!--#include virtual="..." -->
  • 如果 resource-typepath 任何一个不匹配
    • SDI 不会处理,组件仍然正常渲染 HTML

示例:SDI 配置解析

假设你的 OSGi 配置如下/apps/project/config/sling/dynamic-include/config.json):

{
  "include-filter.config.enabled": true,
  "include-filter.config.path": "/content/experience-fragments",
  "include-filter.config.resource-types": [
    "project/components/content/dynamic-footer",
    "project/components/content/dynamic-header"
  ],
  "include-filter.config.extension": "html",
  "include-filter.config.include-type": "SSI",
  "include-filter.config.add_comment": false,
  "include-filter.config.selector": "nocache",
  "include-filter.config.required_header": "Server-Agent=Communique-Dispatcher",
  "include-filter.config.rewrite": true
}

SDI 判断逻辑

页面组件组件 resource-type组件 path符合 SDI 规则?结果
header 组件project/components/content/dynamic-header/content/experience-fragments/homepage✅ 是转换为 SSI
footer 组件project/components/content/dynamic-footer/content/experience-fragments/homepage✅ 是转换为 SSI
hero-banner 组件project/components/content/hero-banner/content/experience-fragments/homepage❌ 不是正常渲染 HTML
header 组件project/components/content/dynamic-header/content/we-retail/page1❌ 不是正常渲染 HTML

结论

  • 只有 同时匹配 pathresource-type 的组件才会触发 SDI 生成 SSI
  • 未匹配的组件 直接输出 HTML,不会被 SDI 拦截。

Dispatcher 访问时的行为

Dispatcher 代理请求 时,SDI 会替换组件 HTML 为 SSI 指令

<!--#include virtual="/content/experience-fragments/footer.html" -->

而非 Dispatcher 访问时(如 AEM 直接渲染页面),组件会正常渲染完整 HTML。


优化建议

如果你想让 更多组件自动转换为 SSI,可以:

  1. 在 OSGi 配置中添加更多 resource-types
  2. 扩展 path 规则,支持更多页面路径
  3. 使用 selector 限制某些页面强制使用 SDI

例如,增加对 /content/we-retail 组件的支持:

"include-filter.config.path": "/content"

这样 /content/we-retail/* 下的符合 resource-types 规则的组件也会被 SDI 转换。


总结

AEM 通过 resource-typepath 同时匹配,才会自动把组件转换为 SSI
符合 SDI 规则的组件,在 Dispatcher 访问时会被替换为 <!--#include virtual="..." -->
SDI 仅拦截匹配的组件,其他组件不会受到影响

这样可以 灵活控制哪些组件通过 SSI 加载,提高页面缓存效率,同时保持部分组件动态加载的能力

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理