【发布时间】:2020-09-21 01:49:09
【问题描述】:
在一个项目中,我必须在 WKWebView 中加载第 3 方网站。我使用 iOS 推荐的 userscript 来做到这一点。我需要点击 src 设置为new Image().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 以外的对象。在互联网上没有任何地方,人们真正讨论过我们是否应该使用代理对象来覆盖原生行为。这样做的想法,听起来很可疑。所以,我想知道我应该怎么做才能点击 Image src 并为我无法控制的网站更改它。另外,我想我不明白 Proxy 对象的正确意图。任何帮助都是轻而易举的事。
我使用的整个代码:
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;
【问题讨论】:
-
看看你的尝试,你似乎只对使用
new Image创建的图像感兴趣,而不是静态HTML中存在<img>标签。这是正确的吗? -
没有。我想拦截所有有 src 的标签。感谢您的回复。刚才,我用 MutableObserver 解决了这个问题。我会回复它。再次感谢您对此进行调查。