如何在XSLT中缓存Include文件?寻求Service Worker之外的方案
客户端XSLT Include文件缓存方案(替代Service Worker)
以下是几种无需Service Worker即可避免XSLT Include重复下载的实用方法:
1. 预加载并内联Include内容
通过JavaScript提前下载所有依赖的XSLT片段,将主XSLT中的<xsl:include>或<xsl:import>标签替换为对应的内联内容,再统一交给XSLTProcessor处理。后续转换时无需再发起网络请求。
示例代码逻辑:
const xsltCache = {}; // 预加载并缓存XSLT文件 async function loadXSLT(url) { if (!xsltCache[url]) { const response = await fetch(url); xsltCache[url] = await response.text(); } return xsltCache[url]; } // 合并主XSLT与所有Include内容 async function getMergedXSLT(mainUrl) { let mainXSLT = await loadXSLT(mainUrl); // 匹配并替换所有include标签 const includeRegex = /<xsl:include\s+href="([^"]+)"\s*\/>/g; mainXSLT = await Promise.resolve(mainXSLT.replace(includeRegex, async (match, href) => { return await loadXSLT(href); })); // 转换为XML文档 const parser = new DOMParser(); return parser.parseFromString(mainXSLT, "application/xml"); } // 使用合并后的XSLT执行转换 async function transformXML(xmlDoc) { const mergedXSLT = await getMergedXSLT("main.xsl"); const processor = new XSLTProcessor(); processor.importStylesheet(mergedXSLT); return processor.transformToDocument(xmlDoc); }
2. 配置HTTP缓存头
直接在服务器端为XSLT Include文件设置合适的HTTP缓存控制头,让浏览器自动缓存这些文件,无需额外客户端代码。常用的响应头配置:
Cache-Control: public, max-age=86400:允许公共缓存(浏览器、CDN)缓存文件1天ETag: "file-unique-hash":通过哈希值验证文件是否更新Last-Modified: Wed, 21 Oct 2023 07:28:00 GMT:通过修改时间判断文件有效性
配置生效后,浏览器会自动复用缓存文件,仅在缓存过期或内容变化时重新请求。
3. 提前合并所有XSLT文件
在构建阶段或服务器端,将所有<xsl:include>/<xsl:import>引用的XSLT内容合并到主XSLT文件中,客户端直接加载单一的合并文件:
- 静态站点:用
xsltproc等工具在发布前手动合并 - 动态站点:服务器接收请求时,实时合并所有依赖片段后返回给客户端
4. 自定义URIResolver拦截资源请求
利用XSLTProcessor的setURIResolver方法,自定义外部资源加载逻辑,直接从内存缓存中读取预加载的XSLT文件,替代网络请求。
示例代码:
const xsltCache = new Map(); // 预加载缓存所有需要的XSLT文档 async function cacheXSLT(url) { const response = await fetch(url); const docText = await response.text(); const parser = new DOMParser(); xsltCache.set(url, parser.parseFromString(docText, "application/xml")); } // 初始化缓存 await Promise.all([cacheXSLT("main.xsl"), cacheXSLT("header.xsl"), cacheXSLT("footer.xsl")]); // 创建处理器并配置自定义资源加载逻辑 const processor = new XSLTProcessor(); processor.setURIResolver(function(uri) { return xsltCache.get(uri) || null; }); // 执行转换 processor.importStylesheet(xsltCache.get("main.xsl")); const resultDoc = processor.transformToDocument(xmlSourceDoc);
内容的提问来源于stack exchange,提问作者user3297232
相关产品推荐
相关产品推荐

