检测JavaScript是否在沙盒Iframe中执行
Detect if JavaScript is Executing In a Sandboxed Iframe?
我有一个产品在Flash中播放视频(如果可用),如果Flash不可用,则返回HTML5。
我找不到一种方法来确定JavaScript是否在具有"沙盒"属性的Iframe中执行,这对我的解决方案来说是必要的,因为沙盒Iframe禁用了所有插件。沙盒iframe可以如此简单:
<iframe src="http://www.cross-domain.com/" sandbox="allow-scripts">
为了确定是否启用了Flash,我使用了swfobject的方法来检查navigator.plugins["Shockwave Flash"].description,即使在沙盒iframe中也会设置该方法。我可以加载swf对象,但它不能播放。
要复制此问题,请访问http://jsfiddle.net/max_winderbaum/9cqkjo45/,打开您的chrome检查器,然后单击"运行"。跨域站点上的脚本将在沙盒iframe的上下文中暂停。
根据W3规范http://dev.w3.org/html5/spec-preview/browsers.html#sandboxing-标志集,在JavaScript可以访问的文档上应该有一个"活动沙箱标志集"(至少我是这样阅读规范的)。iframe的文档上似乎没有设置任何标志。
有人对如何检测JavaScript是否在沙盒iframe中执行有任何想法/解决方案吗?
我会考虑不同类型的iframe(选择第一种适用的情况):
-
带有沙盒脚本浏览上下文标志的Iframe
也就是说,具有不包含
allow-scripts
关键字的sandbox
属性的iframe。此标志阻止脚本执行。特别是,您不能使用脚本来检查iframe是否是沙盒的。
-
没有沙盒源浏览上下文标志的同源iframe
也就是说,不具有
sandbox
属性的同源iframe,或者具有包含allow-same-origin
和allow-scripts
关键字的sandbox
属性的同源IFrame。在这种情况下,可以使用
frameElement
全局属性来访问框架元素(如果不在iframe中使用,则返回null
)。一旦引用了iframe,就可以使用
hasAttribute
或getAttribute
来检查其sandboxed
属性。还有sandboxed
属性,它应该返回DOMSettableTokenList
(旧的浏览器可能会根据旧的规范返回字符串)。 -
没有沙盒源浏览上下文标志的跨源iframe
也就是说,不具有
sandbox
属性的跨原点iframe,或者具有包含allow-same-origin
和allow-scripts
关键字的sandbox
属性的跨原产地iframe。在这种情况下,
frameElement
的使用被阻止:- 根据W3C的说法,它应该抛出一个
SecurityError
异常。这是由Chrome实现的 - 根据WHATWG,它应该返回
null
。这是由Firefox实现的
allow-same-origin
没有多大用处,请考虑假设iframe没有沙盒。 - 根据W3C的说法,它应该抛出一个
-
带有沙盒原始浏览上下文标志的Iframe
也就是说,具有不包含
allow-same-origin
关键字但包含allow-scripts
关键字的sandbox
属性的iframe。与前面的情况一样,
frameElement
的使用被阻止。但是,您可以检测到这种情况,因为
document.domain
将是空字符串。
注意:Firefox将数据URI视为同源,所以没关系。然而,Chrome将它们视为跨源。则frameElement
不起作用,并且无论iframe是否是沙盒的,document.domain
都是空字符串。您可以检查location.protocol
是否为'data:'
字符串来检测数据URI。
通常,您可以尝试类似的方法
function isSandboxedIframe() {
if (window.parent === window) return 'no-iframe';
try { var f = window.frameElement; } catch(err) { f = null; }
if(f === null) {
if(document.domain !== '') return 'unkown'; // Probably 'non-sandboxed'
if(location.protocol !== 'data:') return 'sandboxed';
return 'unkown'; // Can be 'sandboxed' on Firefox
}
return f.hasAttribute('sandbox') ? 'sandboxed' : 'non-sandboxed';
}
项目喷砂器可以帮助您检测是否在沙盒中运行。
沙盒首先检查其自身是否已被框化,然后扫描框架元素的属性以检测有关其自身的一些信息。包括framed
、crossOrigin
、sandboxed
、sandboxAllowances
、unsandboxable
、resandboxable
、sandboxable
。
在我们的例子中,为了检测它本身是否是沙盒的,它检查框架元素是否具有属性sandbox
。
// On below `frameEl` is the detected frame element
try {
result.sandboxed = frameEl.hasAttribute("sandbox");
}
catch (sandboxErr) {
result.sandboxed = null;
if (typeof errback === "function") {
errback(sandboxErr);
}
}
我试图复制你的问题,并测试这个解决方案是否有效,由于安全问题,我不得不将脚本粘贴到窗口中。
<html>
<head>
</head>
<body>
<script>
//Paste the contents of the script(https://raw.githubusercontent.com/JamesMGreene/sandblaster/master/dist/sandblaster.js) here
var result = sandblaster.detect();
if(result.sandboxed === true) {
//sandboxed
}
debugger;
</script>
</body>
</html>
下面是一个演示:http://jsfiddle.net/Starx/tzmn4088/这表明了这一点。
- iFrame url更改时执行函数
- 检测JavaScript是否在沙盒Iframe中执行
- iframe未执行Javascript方法(PHP)
- 如何检测何时执行 iframe 脚本
- iFrame在超时时停止执行
- 如何等到iframe刷新完成后再执行函数
- 如何在 iFrame 的 onload 事件中执行代码
- 每次 iframe 重新导航时执行操作.(JavaScript)
- 在执行函数之前等待多个 iFrame 加载
- Twitter iframe和其他JavaScript获取前者内容的执行顺序
- 加载 iframe 后在 iframe 中执行 JavaScript 代码
- 使用 iframe 的内容在页面上执行 jquery .click()
- 如何在特定的服务器时间在 php 页面上使用 javascript 执行 iframe
- 停止所有代码执行,直到 IFrame 完全加载
- 无法从子 iframe 获取 javascript 执行按钮单击
- 在 iframe 中复制粘贴时执行 Javascript
- 动态放置在 iframe 中的脚本不会执行
- 如何在 javascript 中的 iframe 中创建和执行代码
- 将javascript添加到iframe并执行它
- 正在为iframe执行JS