神的尾巴

全栈工程师、独立开发者

0%

检测当前 iframe 能否打开

今天看到一个比较有意思的面试题:检测当前 iframe 能否打开。

首先我们知道 iframe 只有 onload 事件,没有 onerror 事件,无论 iframe 能否正常加载都会正常触发 onload 事件。

但是由于场景不同,最终所能使用的方案也不同。

非跨域

如果不跨域,那问题就很好解决了,有以下几种方案可以使用:

  1. 使用 ajax 发送一个 head 请求,看状态是否返回 200 (之所以发送 head 请求,是轻量级,响应速度快)。
  2. 检测 iframe 元素特征,在 iframe onload 触发后,检测 html 元素,例如有没有 title,内容是否为空等。

跨域

如果跨域的情况,要看你是否能控制跨域服务器。

能控制跨域服务器

可以使用 jsonp 或 CORS,允许客户端发送跨域 head 请求,来获取是否状态正常

如果不能跨域的情况,见下面的通用方案

通用方案

如果要兼容跨域/非跨域情况,可以使用下面几种通用方案:

  1. 使用定时器检测,如果onload触发时间晚于预设阈值,判定为无法加载;
  2. 使用link标签来测试url能否访问。

下面重点来讲下方案2。

link标签来测试url

我们为什么要使用link标签?

支持跨域的检测标签有如下几个:

  1. script;
  2. img;
  3. link;
  4. video;
  5. audio。

支持 onload 和 onerror 的只有 script 、link、img

之所以不用 img、script的原因是:

  1. img会检测格式,如果不是图片类型,也会触发onerror;
  2. script可能会有安全问题(XSS等)。

检测 demo 代码如下

为了兼容使用了es5语法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<html>

<body>
<iframe id="iframe" onload="frameLoad()" width="100%" height="100%" src="https://baidu1.com">
</iframe>
<script>
function frameLoad() {
console.log('frame load')
}
function accessTest() {
var link = document.createElement('link')
link.rel = "stylesheet"
link.type = "text/css"
// 这里设置需要检测的url
link.href = "https://baidu1.com"
link.onload = function () {
console.log('accessTest success')
}
link.onerror = function () {
console.log('accessTest fail')
}
document.body.appendChild(link)
}
accessTest()
</script>
</body>

</html>
觉得对你有帮助的话,请我喝杯咖啡吧~.