背景:我们有个奇葩网站,用iframe嵌入了很多友方部门的页面,很多部门设置了X-Frame-Options:deny 导致页面展示不出来,如何让页面展示出来,并且只允许在我们的域名下展示出来呢。
先介绍下X-Frame-Options这个header。如果你去查阅相关资料,都会说这个header有三个取值:deny, sameorigin, allow-from https://example.com/ 。甚至有的地方会说allow-from可以写多个域名,allow-from https://example.com/,https://example1.com/。
先解释下这个的含义,deny就是不允许被iframe嵌套。sameorigin表示可以在相同域名下嵌套。allow-from uri标识可以被指定域名嵌套。
所以当我找业务方去改header的时候,他们清一色的给我改成了allow-from https://example.com/,https://example1.com/,https://example1.com/。但是在实际访问的时候会发现报错Invalid 'X-Frame-Options' header encountered when loading xxxx: 'allow-from xxxx,xxx,xxxx' is not a recognized directive. The header will be ignored.
虽然我们的页面可以访问了,但这并不是设置了域名白名单,而是让这个header无效,如果尝试把页面嵌入到其他域名,同样可以访问。到这里我们部门的问题解决了,其他部门的页面可能会存在被iframe嵌套导致的安全问题,不过在国企,其他部门的问题又和我有什么关系呢?但是本着对技术的热爱,还是研究下这个错误。
查了相关报错,有人说是不支持多个域名,于是我用charles重写了header,依然报错。翻看官方文档,发现这个header有兼容性问题
按照这个的说明,FF的最新版也许能支持,换到FF84进行试验,依然报错。继续查阅资料,直到我看到英文版本的mdn
再看中文版
这个值已经被废弃了,但是中文文档没有提示。
那要实现允许指定域名以iframe的方式加载就没有方法了吗?当然不是。一个新的header,Content-Security-Policy
完全可以实现这个功能。他有非常强大的功能,其中frame-ancestors可以控制允许iframe嵌套的父级域名。
使用方法如下
Content-Security-Policy: frame-ancestors https://m.wo.cn
用charles实验一下,设置如上header的时候,页面顺利加载。设置其他域名为白名单,一张苦脸,符合预期。
至此,这个问题顺利解决。