PrimeFaces嵌入PDF在Chrome端仅显示dynamiccontent.properties.jsf问题求助
问题原因与可行解决方案
根本原因
- Chrome 94及以上版本调整了内嵌PDF的文件名读取逻辑:不再优先读取
<embed>/<object>标签的title属性,也不再读取响应头Content-Disposition中携带的文件名,而是直接取当前资源请求路径的最后一段作为PDF显示名称。PrimeFaces media标签默认的动态资源请求路径后缀为dynamiccontent.properties.jsf,因此会被Chrome直接识别为PDF文件名。 - 你遇到的问题和PrimeFaces 6.1版本修复的动态资源未携带文件名漏洞完全无关,属于浏览器规则变更导致的新兼容问题。
可行解决方案
方案1:升级PrimeFaces版本(优先推荐)
PrimeFaces 11.0及以上版本已经针对Chrome的该规则做了适配,会自动将你设置的name参数嵌入到资源请求路径的最后一段,Chrome可直接识别到正确的PDF文件名,无需修改业务代码。
方案2:PrimeFaces 7.0无升级兼容方案
如果你暂时无法升级PrimeFaces版本,可以通过自定义动态资源处理器修改路由规则适配:
- 继承
org.primefaces.application.resource.DynamicContentHandler类,重写handleRequest方法,将配置的PDF文件名追加到请求路径末尾,适配Chrome的读取逻辑 - 在
faces-config.xml中注册你自定义的处理器,覆盖PrimeFaces默认实现
核心参考代码:
@Override public void handleRequest(FacesContext context) throws IOException { Map<String, String> reqParams = context.getExternalContext().getRequestParameterMap(); String pdfName = reqParams.get("name"); // 仅处理PDF类型的动态资源请求 if (pdfName != null && pdfName.toLowerCase().endsWith(".pdf")) { String reqUri = context.getExternalContext().getRequestRequestURI(); // 路径未携带文件名时重定向到带文件名的路径 if (!reqUri.endsWith(pdfName)) { context.getExternalContext().setResponseHeader("Content-Disposition", "inline; filename=\"" + pdfName + "\""); context.getExternalContext().redirect(reqUri + "/" + pdfName); return; } } super.handleRequest(context); }
方案3:前端轻量兼容方案
如果不想修改后端逻辑,可放弃使用PrimeFaces原生media标签,改用HTML原生<embed>标签加载Base64格式的PDF,在资源路径后追加#filename=锚点参数指定文件名,Chrome会优先读取该参数作为PDF显示名:
<embed type="application/pdf" src="data:application/pdf;base64,#{pdfBean.pdfBase64Content}#filename=#{pdfBean.actualPdfName}" width="100%" height="800px">
注意:该方案仅适合10MB以下的小体积PDF,大体积PDF转Base64会大幅增加页面加载耗时
内容的提问来源于stack exchange,提问作者Noel93
相关产品推荐
相关产品推荐

