前言
阿里四面的时候被问到了这个问题,当时第一时间没有反应过来,觉得这个需求好奇特
面试官给了一些提示,我才明白这道题目的意思,最后回答的也是磕磕绊绊
最终实现
实现思路:
1)利用 iframe 创建沙箱,取出其中的原生浏览器全局对象作为沙箱的全局对象
2)设置一个黑名单,若访问黑名单中的变量,则直接报错,实现阻止\隔离的效果
3)在黑名单中添加 document 字段,来实现禁止开发者操作 DOM
4)在黑名单中添加 XMLHttpRequest、fetch、WebSocket 字段,实现禁用原生的方式调用接口
5)若访问当前全局对象中不存在的变量,则直接报错,实现禁用三方库调接口
6)最后还要拦截对 window 对象的访问,防止通过 window.document 来操作 DOM,避免沙箱逃逸
下面聊一聊,为何这样设计,以及中间会遇到什么问题
如何禁止开发者操作 DOM ?
在页面中,可以通过 document 对象来获取 HTML 元素,进行增删改查的 DOM 操作
如何禁止开发者操作 DOM,转化为如何阻止开发者获取 document 对象
1)传统思路
简单粗暴点,直接修改 window.document 的值,让开发者无法获取 document
// 将document设置为null
window.document = null;
// 设置无效,打印结果还是document
console.log(window.document);
// 删除document
delete window.document
// 删除无效,打印结果还是document
console.log(window.document);
好吧,document 修改不了也删除不了