即时更改innerHTML设置

Mir*_*nti 1 javascript hook metaprogramming innerhtml content-security-policy

我需要使用innerHTML快速更改在每个节点上设置的值。

我找到的最接近的解决方案是:

...   
Object.defineProperty(Element.prototype, 'innerHTML', {
    set: function () {
        // get value (ok)
        var value = arguments[0];
        // change it (ok)
        var new_value = my_function(value);
        // set it (problem)
        this.innerHTML = new_value;              // LOOP
    }
}
...
Run Code Online (Sandbox Code Playgroud)

但这显然是一个无限循环。有没有一种方法可以调用原始的innerHTML集?

我也尝试使用代理方式,但无法使其正常工作。

更多细节:

我正在一个实验项目中,该项目使用反向代理来生成CSP策略并将其添加到网站,因此:

  • 网站所有者将意识到这些“ 覆盖
  • 我需要处理可能触发该策略的任何js代码客户端
  • 在评估内容安全策略引擎之前,我需要对其进行修改!(这是需要此“ 不太好的 ”解决方案的主要问题)

nop*_*ppa 5

Obligatory warning: Overriding the setter and getter for any property of Element.prototype is bound to be bad idea in any production-level code. If you use any libraries that rely on innerHTML to work as it should or if there are other developers in the project that don't know of these changes, things might get weird. You will also loose the ability to use innerHTML "normally" in other parts of the app.

就是说,由于您尚未提供有关为什么要执行此操作的任何信息,因此,我假设您已了解警告,并且仍然想覆盖浏览器自身的功能,也许出于开发目的。


解决方案:您正在为重写浏览器的本机设置程序Element.prototype.innerHTML,但也需要原始设置程序来实现您的目标。可以使用Object.getOwnPropertyDescriptor来完成,它类似于的“对应” Object.defineProperty

(function() {
  
  //Store the original "hidden" getter and setter functions from Element.prototype
  //using Object.getOwnPropertyDescriptor
  var originalSet = Object.getOwnPropertyDescriptor(Element.prototype, 'innerHTML').set;
  
  Object.defineProperty(Element.prototype, 'innerHTML', {
    set: function (value) {
        // change it (ok)
        var new_value = my_function(value);
        
        //Call the original setter
        return originalSet.call(this, new_value);
    }
  });
                        
  function my_function(value) {
    //Do whatever you want here
    return value + ' World!';
  }
                        
})();


//Test
document.getElementById('test').innerHTML = 'Hello';
Run Code Online (Sandbox Code Playgroud)
<div id="test"></div>
Run Code Online (Sandbox Code Playgroud)