代码之家  ›  专栏  ›  技术社区  ›  Jorayen

钩住document.createElement脚本以更改src

  •  0
  • Jorayen  · 技术社区  · 8 年前

    我想勾引 document.createElement 改变 src 每个赋值的属性值。

    我在做的是:

    var original = document.createElement;
        document.createElement = function (tag) {
          var element = original.call(document, tag);
          if (tag.toLowerCase() === 'script') {
            Object.defineProperty(element.__proto__, 'src', {
              set: function(newValue) {
                element['src'] = 'test';
              }
            });
          }
          return element;
        };
    

    问题是 element['src'] = 'test'; 正在呼叫 setter 一次又一次导致堆栈溢出。 我尝试了不同的方法,将一个局部变量保存到外部并将其值设置为 newValue 添加一个 getter SRC 返回它的属性。 这种方法的问题在于,如果脚本元素稍后附加到dom中,那么 SRC 属性被添加,就像append方法以某种方式试图获取 SRC 属性,然后以其他方式正常访问它,以便 吸气剂 没有调用,因此留下一个空脚本标记。

    在这种情况下,我能做些什么呢?关于如何才能做到这一点的任何想法,我都可以“替换”要与之一起使用的价值。 SRC 具有其他值的脚本属性?

    编辑: 这就是我最后得到的钩:

        Object.defineProperty(HTMLScriptElement.prototype, 'src', {
      set: function(newValue) {
        const r = /(?:[^:]+:)?\\/\\//;
        if (r.test(newValue)) {
          this.setAttribute("src", 'http://localhost:8080/v1/proxy?url=' + (newValue.startsWith('http') ? encodeURIComponent(newValue) : encodeURIComponent('http:' + newValue)));
        } else {
          this.setAttribute("src", 'http://localhost:8080/v1/proxy?url=' + encodeURIComponent(absolute('${originalHost}', newValue)));
        }
      }
    });
    

    我意识到我需要涵盖所有可能的改变 SRC 属性 script 元素包括 setAttribute('src', '...') 如果我钩住 setAttribute 我会导致堆栈溢出,因为我已经钩住了 SRC 财产 设定器 并使用 设置属性 里面。 如何实现挂钩 设置属性 为了完全控制 SRC 值不会导致堆栈溢出?

    1 回复  |  直到 7 年前
        1
  •  1
  •   Grant Gryczan    8 年前

    把你没有创建的方法和原型弄乱是很糟糕的做法,但这里可能是你的解决方案。

    简单地替换“ element['src'] = 'test'; “随” element.setAttribute('src', 'test'); “。这样你就可以避免使用财产了。这个 setAttribute 方法直接与元素的属性交互,而不是通过浏览器的属性getter。