通过iframe嵌入三方系统时遇到的跨域问题及解决方案

文章目录

    • 背景
    • 实现方式
    • 问题1:通过iframe嵌入后,页面无法正常加载
    • 问题2:Elastic目标页面可正常加载,但无法登录
    • 问题3:获取iframe页面中的dom元素失败
    • 小结

背景

项目中部署了General 和 Elastic kabana来监控服务器性能,因为部署在不同的服务器,每次查看时需要打开不同的系统,非常麻烦,所以将他们内嵌到中心系统里方便查看。

实现方式

前端使用vue3,通过路由meta获取iframe加载的url。

const frameSrc = ref<string>("");
if (unref(currentRoute.meta)?.frameSrc) {
  frameSrc.value = unref(currentRoute.meta)?.frameSrc as string;
}

<iframe :src="frameSrc" class="frame-iframe" ref="frameRef" />

问题1:通过iframe嵌入后,页面无法正常加载

控制台报错Refused to display 'http://xxx.xxx.xxx.xxx:8008/' in a frame because it set 'X-Frame-0ptions' to 'deny'

原因:
当目标网站设置了X-Frame-OptionsDENYSAMEORIGIN时,会导致目标网址无法被通过iframe加载。

解决方案:
将目标网址的X-Frame-0ptions设置为 ALLOW-FROM uri:表示页面只能被指定uri的iframe嵌入。

问题2:Elastic目标页面可正常加载,但无法登录

查看Elastic kabana官方文档 需将xpack.security.sameSiteCookies 设置为none

Cookie SameSite标记:

SameSite:默认情况下,浏览器要求跨站点的第三方Cookie具有SameSite属性设置(通常为Lax或Strict)。如果子系统返回的Cookie没有设置SameSite属性,或者设置为None并且没有Secure标记,浏览器也会拒绝接受该Cookie。

但这简单的操作之后并无法正常访问,继续排查。

Cookie Secure标记:

Secure标记是指当浏览器向服务器发送请求时,只有使用HTTPS协议的连接才会传递该Cookie。如果服务器返回的Set-Cookie头部没有包含Secure标记,浏览器就会拒绝接收该Cookie,并将其视为不安全的Cookie。

SameSite=none 只支持HTTPS接口。如果要设置该值,需要在对应的Cookie上同时设置Secure属性

解决方案:

将目标地址访问方式升级为https,并添加Secure标记

问题3:获取iframe页面中的dom元素失败

因嵌入的第三方系统与父系统是完全不一样的用户体系,并且没必要做统一认证,所以想要在iframe中直接获取到用户名密码输入框模拟自动登录,但在控制台中报错。

获取方式:


const frameRef = ref(null);

const iframe = unref(frameRef);
const usernameInput =iframe.contentWindow.document.getElementsByClassName("username");
console.log(usernameInput);