在一个项目中,我必须在WKWebView中加载第三方网站。我使用iOS推荐的userscript来做到这一点。我需要点击设置为new Image().src
的src并根据需要进行更改,甚至不通知加载的网站。我用Proxy object的自定义类伪造了Image。它很好地伪造了。但这是一个hack,我对此没有信心,因为它将永远有效。我看到它在执行appendChild()时失败。我尝试过的想法是:
const imgProxy = new Proxy(Image, {
set:(a,b,c,d) => {
console.log(`target: ${a} src: ${String(c)}`);
return Reflect.set(a,b,c,d);
}
});
const img = new imgProxy(150,150);
img.src = 'https://via.placeholder.com/150';
document.body.appendChild(img);
有效。但这并没有遇到trap方法,这不是我的意图。然后,我尝试使用new Proxy(new Image(150,150), ...)
。这属于陷阱,但不适用于appendChild(),因为appendChild拒绝不知道Node以外的对象。在Internet上没有哪个地方真正讨论过我们是否应该使用Proxy对象来覆盖本地行为。这样做的想法,听起来很可疑。因此,我徘徊了应该怎么做才能使用Image src并将其更改为我无法控制的网站。另外,我认为我不理解代理对象的正确意图。任何帮助都是轻而易举的。
我使用的整个代码:
const NativeImage = Image;
class CustomImage {
constructor(width, height) {
const nativeImage = new NativeImage(width, height);
const handler = {
set: (target, prop, value) => {
if (prop === 'src') {
value = modifyAsPerMyNeed(value) || value;
}
return (nativeImage)[prop] = value;
},
get: (target, prop) => {
let result = target[prop];
if (typeof result === 'function') {
result = result.bind(target);
}
return result;
}
};
const proxy = new Proxy(Image, handler);
try {
proxy[Symbol.toStringTag] = 'HTMLImageElement';
} catch (e) {
console.log(`HSIWKUserScript error : ${e}`);
}
CustomImage.prototype[Symbol.toStringTag] = NativeImage.prototype.toString();
return proxy;
}
}
if ('toSource' in NativeImage) { // FF extra
Object.defineProperty(CustomImage, 'toSource', {
enumerable: false,
configurable: false,
writable: true,
value: () => {
return (NativeImage as any).toSource();
}
});
}
Object.defineProperty(CustomImage, 'name', {
enumerable: false,
configurable: false,
writable: false,
value: 'Image'
});
Object.defineProperty(CustomImage, 'toString', {
enumerable: true,
configurable: false,
writable: true,
value: () => {
return NativeImage.toString();
}
});
window.Image = CustomImage;
昨天我整天都很愚蠢。我使用的是MutationObserver,并且工作正常。这比需要拦截javascript对象以进行DOM拦截要优越得多。图像对象最终在DOM中插入img标签。将src插入DOM后,我可以立即对其进行更改。但是我不必要地写了Image的包装。删除该包装程序可以很好地完成工作,但可以满足我们拦截和修改src属性的意图。