检测自己网站是否被嵌套在iframe下并从中跳出

iframe被用于将一个网页嵌套在另一个网页中,有的时候这会带来一些安全问题,这时我们就需要一些防嵌套操作了。

本文分为俩部分,一部分讲解如何检测或者禁止嵌套操作,另一部分讲解如何从嵌套中跳出。

末尾放了正在使用的完整代码,想直接用的可以拉到最后。

效果

当存在嵌套时会出现一个蒙版和窗口,提示用户点击。

点击后会在新窗口打开网站页面。

嵌套检测

设置响应头

响应头中有一个名为X-Frame-Options的键,可以针对嵌套操作做限制。

它有3个可选值:

DENY:拒绝所有

SAMEORIGIN:只允许同源

ALLOW-FROM origin:指定可用的嵌套域名,新浏览器已弃用

后端检测(以PHP为例)

通过获取$_SERVER中的HTTP_REFERERHTTP_SEC_FETCH_DEST值,可以判断是否正在被iframe嵌套

ini 复制代码
// 如果不是iframe,就为空的字符串
$REFERER_URL = $_SERVER['HTTP_REFERER'];

// 资源类型,如果是iframe引用的,会是iframe
$SEC_FETCH_DEST = $_SERVER['HTTP_SEC_FETCH_DEST'];

// 默认没有被嵌套
$isInIframe = false;

if (isset($_SERVER['HTTP_REFERER'])) {
  $refererUrl = parse_url($_SERVER['HTTP_REFERER']);
  $refererHost = isset($refererUrl['host']) ? $refererUrl['host'] : '';

  if (!empty($refererHost) && $refererHost !== $_SERVER['HTTP_HOST']) {
    $isInIframe = true;
  }
}

// 这里通过判断$isInIframe是否为真,来处理嵌套和未嵌套执行的动作。
if($isInIframe){
  ....
}

前端检测(使用JavaScript)

通过比较window.self(当前窗口对象)和window.top(顶层窗口对象)可以判断是否正在被iframe嵌套

javascript 复制代码
if (window.self !== window.top) {
  // 检测到嵌套时该干的事
}

从嵌套中跳出

跳出只能是前端处理,如果使用了PHP等后端检测,可以直接返回前端JavaScript代码,或者HTML的A标签设置转跳。

JavaScript直接转跳(不推荐)

不推荐是因为现在大多浏览器为了防止滥用,会阻止自动弹出新窗口。

javascript 复制代码
window.open(window.location.href, '_blank');

A标签点击转跳(较为推荐)

当发生了用户交互事件,浏览器就不会阻止转跳了,所以这是个不错的方法。

ini 复制代码
<a href="https://www.9kr.cc" target="_blank">点击进入博客</a>

JavaScript+A标签(最佳方法)

原理是先使用JavaScript检测是否存在嵌套,

如果存在嵌套,再使用JavaScript加载蒙版和A标签,引导用户点击。

这个方法直接查看最后一节。

正在使用的方法

也就是上一节说的JavaScript+A标签。

先给待会要显示的蒙版和A标签窗口设置样式

css 复制代码
/* 蒙版样式 */
.overlay1 {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        background-color: rgba(0,0,0,0.5); /* 半透明背景颜色 */
        z-index: 9999; /* 确保蒙版位于其他元素之上 */
        display: flex;
        align-items: center;
        justify-content: center;
    }
        
    /* 窗口样式 */
    .modal1 {
        background-color: #fff;
        padding: 20px;
        border-radius: 5px;
    }

然后是检测和加载蒙版+A标签的JavaScript代码

ini 复制代码
if (window.self !== window.top) {
	// 创建蒙版元素
	var overlay = document.createElement('div');
	overlay.className = 'overlay1';

	// 创建窗口元素
	var modal = document.createElement('div');
	modal.className = 'modal1';

	// 创建A标签元素
	var link = document.createElement('a');
	link.href = 'https://www.9kr.cc';
	link.target = '_blank'; // 在新窗口中打开链接
	link.innerText = '点击进入博客';
	//link.addEventListener('click', function(event) {
	//    event.preventDefault(); // 阻止默认链接行为
	//    alert('Test');
	//});

	// 将A标签添加到窗口元素中
	modal.appendChild(link);

	// 将窗口元素添加到蒙版元素中
	overlay.appendChild(modal);

	// 将蒙版元素添加到body中
	document.body.appendChild(overlay);
}

博客的话,只需要在主题上设置自定义CSS自定义JavaScript即可


博客原文:www.9kr.cc/archives/41... 资源编号:2023083001

相关推荐
野盒子1 分钟前
前端小程序面试题
前端·小程序·notepad++
开始编程吧1 分钟前
【HarmonyOS5】鸿蒙×React Native深度实践:跨端应用开发的「代码级」融合
前端
Re2751 分钟前
什么期末还要考html,我还没上车啊。期末慌了!HTML 速成攻略来袭
前端
irises2 分钟前
简单实现一个水印插件
前端·源码
我爱吃橘子2 分钟前
解决 Element UI 单选框组内输入框光标移动报错问题
前端
若梦plus3 分钟前
React19 路由方案与原理详解
前端·javascript·react.js
猩猩程序员4 分钟前
使用用 Rust 开发的 Oxlint 1.0 发布,赶紧上车
前端
GIS之路4 分钟前
OpenLayers 可视化之热力图
前端
若梦plus6 分钟前
React 路由库之 @tanstack/router
前端·react.js
晴殇i21 分钟前
前端工程师必须掌握的SEO实战指南
前端·javascript·面试