Windows IIS 10下DomPDF无法显示img标签内base64编码SVG问题
问题背景
- 基于Ubuntu 21.10 + Laravel Sail环境开发了带PDF生成功能的Laravel应用,部署到搭载IIS 10的Windows Server服务器后,PDF内图片全部加载失败
- 相同代码在开发环境下运行完全正常
原实现逻辑
PDF内嵌入SVG图片的模板代码:
<img style="width: 200px;" src="data:image/svg+xml;base64,{{ $base64_image }}" alt="">
$base64_image变量生成逻辑:
base64_encode(str_replace('<svg', '<svg fill="#000000" ',file_get_contents("img/image.svg")))
逻辑为通过file_get_contents()读取本地SVG文件,给SVG标签追加黑色填充属性后转base64字符串,传入img标签src属性完成渲染。
已做排查(均无效)
- 在IIS站点管理器中更新MIME Types配置
- 修改
web.config配置放行SVG资源 - 替换为线上托管的PNG图片地址测试
报错现象
生成的PDF中所有图片位置仅显示占位方块,抛出错误提示:
image not found or type unknown
问题原因&修复方案
你之前做的MIME、web.config配置都是调整IIS处理静态资源访问的规则,PDF生成是PHP进程在后端完成的渲染,和IIS的静态资源放行逻辑完全无关,排查方向错了。按下面顺序修复:
- 修复本地文件读取路径问题
代码里用的img/image.svg是相对路径,Linux容器下Laravel Sail的PHP工作目录和Windows IIS下的PHP工作目录不一致,会直接读不到SVG文件。把相对路径改成Laravel框架封装的绝对路径辅助函数调用:// 确认SVG文件存放在public/img/目录下,用public_path拼绝对路径 $svgContent = file_get_contents(public_path('img/image.svg')); - 补全SVG必要命名空间,解决Windows下PDF引擎解析SVG失败问题
你现在用str_replace直接插入fill属性的写法太粗暴,如果原SVG文件没带XML命名空间声明,Windows环境下的Dompdf(Laravel PDF生成通用依赖)会直接识别不了SVG格式。替换属性前先补全必要的命名空间:$svgContent = file_get_contents(public_path('img/image.svg')); // 检查SVG是否带标准命名空间,没有就补上 if (!str_contains($svgContent, 'xmlns="http://www.w3.org/2000/svg"')) { $svgContent = str_replace( '<svg', '<svg xmlns="http://www.w3.org/2000/svg" fill="#000000" ', $svgContent ); } else { $svgContent = str_replace('<svg', '<svg fill="#000000" ', $svgContent); } $base64_image = base64_encode($svgContent); - 修复远程图片加载失败问题
连线上PNG都加载失败,是IIS对应运行的PHP版本关闭了远程文件读取权限。找到IIS站点绑定的PHP版本对应的php.ini配置文件(注意别改到PHP CLI命令行版本的配置),把allow_url_fopen = Off调整为allow_url_fopen = On,保存后重启对应IIS应用池即可生效。 - 额外校验
Linux文件系统大小写敏感,Windows文件系统虽然默认不敏感,但如果路径、文件名存在大小写拼写偏差,偶尔也会出现文件读取异常,确认public/img/目录下的文件名确实为image.svg,无大小写错误。
内容的提问来源于stack exchange,提问作者Avrgebro
相关产品推荐
相关产品推荐

