在HTML页面中使用Iframe嵌入Jenkins报告时,相对路径引发的404错误是开发者经常遇到的问题。Jenkins生成的报告通常包含大量相对路径的静态资源引用,当报告被嵌入到不同域或者不同路径的页面中时,这些相对路径的解析基准会发生变化,最终导致资源无法正确加载。

问题产生的原因
Jenkins报告中的静态资源比如CSS、JS、图片等,大多使用相对路径引用。相对路径的解析规则是相对于当前页面的base标签或者页面的访问URL。当Jenkins报告直接访问时,浏览器会以报告的访问地址作为基准解析相对路径,资源可以正常加载。但是当报告被放入Iframe嵌入到其他HTML页面时,Iframe内部的相对路径解析基准默认是Iframe的src属性地址,如果Iframe的src指向的是Jenkins的报告地址,理论上是没问题的,但实际场景中经常会出现Iframe的src指向的是代理地址、或者Jenkins报告被重新部署到不同路径的情况,这时候相对路径的基准就会和资源的实际路径不匹配,最终触发404错误。
常见的解决方法
1. 设置Iframe的src为Jenkins报告的直接访问地址
如果Jenkins服务可以直接访问,最简便的方式是将Iframe的src属性直接设置为Jenkins报告的实际访问URL,这样Iframe内部的相对路径会直接以该报告地址为基准解析,和直接访问报告的路径解析规则一致,不会出现路径偏差。
<!-- 假设Jenkins报告的访问地址是 http://192.168.0.1:8080/job/test/lastReport/ --> <iframe src="http://192.168.0.1:8080/job/test/lastReport/" width="100%" height="800px" frameborder="0"> </iframe>
2. 通过反向代理统一路径基准
如果因为跨域或者权限问题,不能直接使用Jenkins的原始地址,可以通过Nginx等反向代理工具,将Jenkins的报告路径和当前页面的路径映射到同一个基准下。比如当前页面的访问地址是http://ipipp.com/report/,可以将/jenkins-report/路径代理到Jenkins的报告地址,这样Iframe的src使用/jenkins-report/,相对路径的解析基准就和代理后的路径一致。
Nginx的配置示例如下:
server {
listen 80;
server_name ipipp.com;
# 当前页面所在路径
location /report/ {
root /usr/share/nginx/html;
index index.html;
}
# 代理Jenkins报告路径
location /jenkins-report/ {
proxy_pass http://192.168.0.1:8080/job/test/lastReport/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}此时HTML页面的Iframe可以这样配置:
<iframe src="/jenkins-report/" width="100%" height="800px" frameborder="0"> </iframe>
3. 修改Jenkins报告的相对路径为绝对路径
如果可以修改Jenkins报告的生成逻辑,可以在生成报告时将所有的相对路径替换为绝对路径。比如Jenkins的HTML报告是通过构建脚本生成的,可以在生成后执行路径替换命令,将所有src="css/这样的相对路径替换为src="http://192.168.0.1:8080/job/test/lastReport/css/这样的绝对路径。以下是使用Shell脚本替换路径的示例:
# 假设Jenkins报告生成在路径 /var/jenkins_home/jobs/test/htmlreports/report
REPORT_DIR="/var/jenkins_home/jobs/test/htmlreports/report"
JENKINS_REPORT_BASE="http://192.168.0.1:8080/job/test/lastReport/"
# 查找所有html文件,替换相对路径为绝对路径
find $REPORT_DIR -name "*.html" -type f | while read file; do
sed -i "s|src=\"css/|src=\"${JENKINS_REPORT_BASE}css/|g" $file
sed -i "s|src=\"js/|src=\"${JENKINS_REPORT_BASE}js/|g" $file
sed -i "s|src=\"images/|src=\"${JENKINS_REPORT_BASE}images/|g" $file
sed -i "s|href=\"css/|href=\"${JENKINS_REPORT_BASE}css/|g" $file
done4. 在Iframe内部添加base标签
如果可以在Jenkins报告的HTML头部添加base标签,那么可以指定相对路径的解析基准。比如在报告的<head>部分添加<base href="http://192.168.0.1:8080/job/test/lastReport/">,这样即使报告被嵌入到Iframe中,所有的相对路径都会以base标签指定的地址为基准解析,不会出现路径错误。
如果是通过Jenkins的插件生成报告,可以查看插件的配置选项,是否支持自定义头部内容,添加base标签。如果是自定义的构建脚本生成报告,可以直接在生成报告时插入该标签。
不同方案的适用场景
| 方案 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| 直接设置src为Jenkins地址 | Jenkins服务可直接访问,无跨域限制 | 配置简单,无需额外改动 | 有跨域问题时无法使用,路径暴露Jenkins真实地址 |
| 反向代理统一路径 | 需要隐藏Jenkins地址,存在跨域问题 | 路径统一,可解决跨域,灵活性高 | 需要配置反向代理服务,有一定运维成本 |
| 修改为绝对路径 | 可以修改Jenkins报告生成逻辑 | 路径固定,不会出现解析偏差 | 需要修改报告生成流程,每次重新生成报告都需要替换 |
| 添加base标签 | 可以在报告头部插入自定义内容 | 改动小,针对性强 | 需要报告生成支持自定义头部,部分场景无法修改报告内容 |
注意事项
- 如果Jenkins服务开启了访问权限控制,Iframe嵌入时可能需要处理认证问题,比如添加Cookie或者Token参数,否则即使路径正确也会因为无权限访问返回404。
- 使用反向代理时,需要注意转发请求时的Header配置,避免Jenkins因为Host头不正确返回错误页面。
- 修改报告路径时,要确认所有相对路径的引用场景,避免遗漏部分资源的路径替换,导致部分资源仍然加载失败。