iframe实现与父页面跨域隔离的JavaScript 代码沙箱

 更新时间:2023年05月16日 10:59:54   作者:知名喷子  
这篇文章主要介绍了使用iframe实现与父页面跨域隔离的JavaScript代码沙箱,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

正文

假如让你实现一个在线的 JavaScript 代码运行环境,要求用户代码不能对页面进行修改,以避免潜在的安全问题,你会怎么做?

使用 with?使用 proxy?OK ,都可以,但是这两种方法都需要关注很多细节,否则用户依旧有可乘之机,这样一来你的实现里面就会有一个很长长长长长长长的操作黑名单。

除此之外,我们还可以专门部署一个页面,将代码提到服务端渲染成页面,再通过 iframe 去访问,如果 iframe 与父页面之间是跨域的话可以达到很高的安全性——那么能不能不看后端的脸色,完全使用浏览器来实现类似的沙箱呢?

当然可以——

1. iframe

对前端页面而言,跨域是页面与页面之间的鸿沟,但这并不意味着我们必须重新打开一个页面来运行新的代码,因为我们可以使用 <iframe> 标签:

<iframe src="www.xxxx.xxx"></iframe>

对于同域的 iframe ,我们可以直接通过 .contentWindow 访问并操作它的全局对象,然后直接往里面执行 JavaScript:

document.querySelector('iframe')
  .contentWindow
  .eval('alert("hello world!");');

但是同域页面的子页面是可以与父页面进行互操作的,

2. data URL

你可能在一些页面里见过小图片不使用网络链接,而是采用一个 data:image/png;base64 xxxxxxx 风格的 URL ,这种 URL 就是 data URL


除了 data URL 之外你可能还见过 blob:// 开头的 URL —— Object URL。不过 Object URL 与当前页面是同域的,而 data URL 与当前页面是跨域的。所以我们可以在 iframe 使用 data URL 来进行跨域隔离

3. 将 JavaScript 代码变成 data URL

我们可以直接将 JavaScript 片段变成 data:application/javascript, 的 URL ,但是这样有一个问题: iframe 打开这样的 URL 的时候,会显示代码原文而不是执行代码,这个行为其实和你直接在浏览器地址栏输入 JS 的 URL 是一样的。
所以我们需要将 JavaScript 代码拼接到 html 里面,再变成 data URL ,然后交给 iframe 去加载:

const javaScriptFragment = `
alert('hello world');
`;
const htmlFragment = `
<!doctype html>
<html>
  <head>
    <meta chatset="utf-8" />
  </head>
  <body>
    <script>${javaScriptFragment}</script>
  </body>
</html>
`;
const dataUrl = `data:text/html,${htmlFragment}`;
// 注意,如果代码片段中含有中文的话,需要使用 encodeURIFragment 转义 htmlFragment
document.querySelector('iframe').src = dataUrl;

4. 如果需要获取执行结果的话,基于 postMessage 定制通信机制

如果我们不但要做沙箱隔离,还被要求获取运行结果的话,则可以做一个通信机制,让 iframe 获取到用户代码执行结果, iframe 与父页面之间最好的跨域通信方法莫过于 postMessage
除了获取结果之外,还可以将通信机制进一步扩展成为 RPC ,这样可以实时修改页面里的代码来查看效果,类似于 codepen 。

具体实现与主题不是强相关,这里就不写了,更多关于JavaScript iframe页面跨域隔离的资料请关注脚本之家其它相关文章!

相关文章

  • SyntaxHighlighter语法高亮插件使用说明

    SyntaxHighlighter语法高亮插件使用说明

    SyntaxHighlighter语法高亮插件使用说明,需要的朋友可以参考下。
    2011-08-08
  • js控制TR的显示隐藏

    js控制TR的显示隐藏

    在很多现实的场景中,有的文本框我们希望在选择“是”的按钮之后才出现,这就需要js控制TR的隐藏和显示,如何控制,本文为大家揭晓
    2016-03-03
  • Bootstrap table使用方法总结

    Bootstrap table使用方法总结

    这篇文章主要总结介绍了Bootstrap table的使用方法,服务器分页、客户端分页的转换,table刷新,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-05-05
  • iframe里的页面禁止右键事件的方法

    iframe里的页面禁止右键事件的方法

    这篇文章主要介绍了iframe里的页面禁止右键事件的方法,需要的朋友可以参考下
    2014-06-06
  • js 使用ajax设置和获取自定义header信息的方法小结

    js 使用ajax设置和获取自定义header信息的方法小结

    这篇文章主要介绍了js 使用ajax设置和获取自定义header信息的方法,结合实例形式总结分析了js 使用ajax自定义设置和获取header响应信息相关操作技巧与使用注意事项,需要的朋友可以参考下
    2020-03-03
  • ES6如何用一句代码实现函数的柯里化

    ES6如何用一句代码实现函数的柯里化

    这篇文章主要介绍了ES6如何用一句代码实现函数的柯里化,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-01-01
  • 浅析JavaScript对象转换成原始值

    浅析JavaScript对象转换成原始值

    这篇文章主要介绍了浅析JavaScript对象转换成原始值,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下,需要的朋友可以参考一下
    2022-07-07
  • javascript实现的颜色块滑动的动态效果

    javascript实现的颜色块滑动的动态效果

    javascript实现的颜色块滑动的动态效果...
    2007-08-08
  • JavaScript变量中var,let和const的区别

    JavaScript变量中var,let和const的区别

    这篇文章主要介绍了JavaScript变量中var,let和const的区别,JavaScript中一共有3种用来声明变量的关键字,分别是var、let和const,文章通过围绕主题展开对三个关键词的详细介绍,需要的朋友可以参考一下
    2022-09-09
  • 再谈javascript注入 黑客必备!

    再谈javascript注入 黑客必备!

    这篇文章主要为大家详细介绍了js注入,黑客之路必备!本文告诉大家js注入是什么,js注入攻防如何进行,感兴趣的小伙伴们可以参考一下
    2016-09-09

最新评论