记一次在 iframe 中处理浏览器安全策略问题

2024-07-09

上周有现网用户反应之前做的一个功能:在网页中嵌入他们其他平台的页面内容不能正常显示了。

当时做这个功能也比较简单,使用 iframe 嵌入他们需要展示的网页,跨域和白名单等问题对方处理,当时部署到现网是可以正常显示的。

问题现象

出现的问题现象是,现在需要在浏览器中先打开嵌入的网页,才能在我负责的项目中正常显示,如果仅打开我的项目,嵌入的网页不能正常打开。

原因分析

上现网看了一下,界面报这个错

202407091520608因为之前的跨域和白名单问题已经解决了,就想到了应该是 SSL 证书的问题,由于两个网页的证书不匹配,并且由于是政府项目,是内网访问的,没有正式的证书,导致每次登录时浏览器都会警告 Your connection is private,需要手动确认才能进入。所以就会导致问题现象,因为没有手动确认导致页面不能正常显示。

解决方法

有以下几种解决方案

  1. 关闭并忽略浏览器的安全策略(可以但是不推荐,需要保护用户数据安全,并且不可能让用户去改设置)

  2. 全部改为 http(改动太大不现实)

  3. 使用 nginx 代理(可行)

最终解决方法

最终使用的 nginx 完美的解决了这个问题。

例如,我的项目的地址是 https:a.b:c,而需要嵌入的地址是 https://d.e:f/shareDashboard/xxx。在为改动之前我的 iframe 是这样写的

<iframe
  style={{ width: '100%', height: '100vh' }}
  frameBorder={0}
  src='https://d.e:f/shareDashboard/a464944fa49f4d4baf07225d6e64fbe1?type=NONE'
/>

改动后

<iframe
  style={{ width: '100%', height: '100vh' }}
  frameBorder={0}
  src='https:a.b:c/shareDashboard/a464944fa49f4d4baf07225d6e64fbe1?type=NONE'
/>

配置 nginx

location ~* ^/(shareDashboard|shareChart|shareStoryPlayer|shareDataPortal) {
  proxy_pass https://d.e:f;
  proxy_connect_timeout 300s;
  proxy_send_timeout 300s;
  proxy_read_timeout 300s;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto http;
}
location ~* ^/(static|api|antd|geoJson|custom-chart-plugins|images|resources) {
  proxy_pass https://d.e:f;
  proxy_connect_timeout 300s;
  proxy_send_timeout 300s;
  proxy_read_timeout 300s;
  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header X-Forwarded-Proto http;
 }

当路由匹配到 shareDashboard 时,会转发到 https://d.e:f 上并获取对象的静态资源返回

这种方式适合于两个都是 https 的情况。