我试图挂钩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
属性然后正常访问它没有调用getter
,因此我留下了一个空脚本标签。
在这种情况下我该怎么办,关于我如何能够做到这一点的任何想法我可以用另一个值“替换”用于脚本的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
属性setter
并在其中使用setAttribute
。我怎样才能实现挂钩setAttribute
以便完全控制src
值而不会导致堆栈溢出?
弄乱你没有创建的方法和原型是非常糟糕的做法,但无论如何这里可能是你的解决方案。
只需将“element['src'] = 'test';
”替换为“element.setAttribute('src', 'test');
”即可。这样你就可以避免使用该属性。 setAttribute
方法直接与元素的属性交互,而不是通过浏览器的属性getter。