HTML5 MutationObserver检测页面劫持

很久没写博客了,业务一直在变化,陆陆续续的作了不少web app,被业务流淹没就不多有机会去反思,前端技术发展如此之快,经常有种不学则退的恐慌,一种技术还没吃透就涌出新的技术,而后一波人又打着各类旗帜去宣传,想偷懒都不行,大脑彻底不够用。html

Nodejs,AngularJS,vuejs,React,grunt,gulp,webpack...Fuck!前端

HTML5的水很深很深,感受还有不少技术没有挖掘和使用。无心中发现HTML5 DOM4级MutatioObserver方法,能够检查页面中的DOM是否发生变化,说到这也许你们知道能够用来干吗了。vue

确实,前段时间咱们遇到了web app被运营商劫持的问题,不清楚哪一个环节出了问题,换了https按理说应该不会再出现,后来想到用相似GA统计的方式去统计页面是否被注入了js脚本或者iframe,而后经过日志去查看异常问题。webpack

劫持问题无非就是页面被修改了,DOM结构发生变化了被插入了小广告。看到MutatioObserver方法有种豁然开朗的感受,虽然不能解决被劫持的问题,可是也能查看被注入了什么,也算涨了见识。web

概述gulp

 MutationObserver从字面上含义就是发现突变。它能够监听页面的DOM元素是否发生了变化,而后给出通知。数组

Constructor

MutationObserver()

new MutationObserver(callback)

callback,当每次DOM发生变化的时候都会触发callback,你们也许就会问,那要是频繁修改dom,那这个callback就会频繁触发,性能上怎么办?实际上,MutationObserver并非每次dom发生变化的时候当即触发,仍是等全部的dom操做完成以后一次执行,也就是说它是异步的。app

举个栗子:dom

<body>
  <ul id="container"></ul>
</body>
var callback=function(){
  console.log("Dom changed");
};
var mutationObserver=new MutationObserver(callback);
var otpions={
  subtree:true,
  childList:true
};
mutationObserver.observe(document.body,otpions);
window.onload=function(){
  for(var i=0;i<10;i++){
    var li=document.createElement("li");
    li.innerText="这是";
 document.getElementById("container").appendChild(li);
  }
};

http://jsbin.com/nimilelote/edit?html,js,console,output异步

咱们像DOM元素中插入了10次,实际上oberve只执行了一次,是在全部的dom操做完成以后触发的。

 

mutationObserver实例有三个方法。

observe(target,options)  //给制定的DOM注册一个事件,若是DOM发生变化就会发送通知。target是目标元素,好比body,options是配置哪写dom发生变化时才发送通知

disconnect();    //终止监听DOM变化,直到从新实例化

takeRecords()   //清除变更记录,即再也不监听还没发生的DOM变化

 

observe实例化配置:

childList:设置为true表示监听指定元素的子元素的变更;

attributes:设置为true表示监听指定元素的属性的变更;

characterData:设置为true表示监听指定元素的data变更;

subtree:设置为true表示不紧监听目标元素也同时监听其子元素变更;

attributeOldValue:在attributes属性已经设为true的前提下,若是须要将发生变化的属性节点以前的属性值记录下来(记录到下面MutationRecord对象的oldValue属性中),则设置为true;

characterDataOldValue:在characterData属性已经设为true的前提下,若是须要将发生变化的characterData节点以前的文本内容记录下来(记录到下面MutationRecord对象的oldValue属性中),则设置为true.

attributeFilter:一个属性名数组(不须要指定命名空间),只有该数组中包含的属性名发生变化时才会被观察到,其余名称的属性发生变化后会被忽略.

// Firefox和Chrome早期版本中带有前缀
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver

// 选择目标节点
var target = document.querySelector('#some-id');
 
// 建立观察者对象
var observer = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
    console.log(mutation.type);
  });    
});
 
// 配置观察选项:
var config = { attributes: true, childList: true, characterData: true }
 
// 传入目标节点和观察选项
observer.observe(target, config);
 
// 随后,你还能够中止观察
observer.disconnect();
相关文章
相关标签/搜索