记一次Umami无法通过Iframe嵌入网站的解决办法

记一次Umami无法通过Iframe嵌入网站的解决办法

事情起因

最近刚部署好新的博客,然后在逐步完善博客的功能,现在使用的Halo的Clarity主题,该主题由HandSome & 纸鹿开发,HandSome有开发一个数据看板的插件,能够搭配Clarity主题食用,但是该插件没有提供统计脚本的引入集成,刚好Halo官方有一个Umami插件能够集成统计脚本。该插件启用后,会在控制台新增一个菜单,该菜单嵌入了Umami的共享网页,能够便于管理员快捷访问统计页面。

然后捏,发现这个页面没法访问,提示umami.uomn.cn 拒绝了我们的连接请求

问题根源

在通过查看开发者工具的控制台和网络发现,Umami设置了限制 iframe 嵌入的规则

控制台中的错误信息:

# 仅允许自身域名作为父框架
Framing 'https://umami.uomn.cn/' violates the following Content Security Policy directive: "frame-ancestors 'self'". The request has been blocked.

请求头中的信息:

# 仅允许同域名嵌入
x-frame-options: SAMEORIGIN

Umami 为了防止点击劫持(Clickjacking),默认会在响应头中设置限制 iframe 嵌入的规则:

X-Frame-Options:常见值为 DENY(禁止所有嵌入)、SAMEORIGIN(仅允许同域名嵌入);
Content-Security-Policy (CSP):包含 frame-ancestors 'self'(仅允许同域名嵌入)或 frame-ancestors 'none'(禁止所有)。

这两个规则刚好就是上方所确认的信息

解决方案

小知识:frame-ancestors 'self' 是更高优先级的 CSP 规则(现代浏览器优先遵循 CSP,而非 X-Frame-Options

方案一:修改Nginx

我是使用1Panel部署的Umami并通过Nginx反代的

# 清除容器携带的响应头
proxy_hide_header Content-Security-Policy; 
proxy_hide_header X-Frame-Options;   
# 自己加的响应头    
add_header Content-Security-Policy "frame-ancestors 'self' https://uomn.cn https://*.uomn.cn; default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self'; font-src 'self'; object-src 'none'; base-uri 'self';" always;
# 兼容旧版浏览器
add_header X-Frame-Options "ALLOW-FROM https://uomn.cn https://*.uomn.cn" always;
注意将上方响应头内的网站地址修改为你需要嵌入Umami的网站地址

方案二:本地编译编译Docker

Umami官方提供了一个变量,该变量在容器进行编译的时候才会生效,这个方案适合动手能力强的小伙伴

由于我动手能力不强,所以我就不动手了哈,下边是官方文档可以参考

最终结果

结果就是能正常嵌入访问了,如下图所示

评论区