JavaScript中的本地图像对象代理

问题描述 投票:2回答:1

在一个项目中,我必须在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;

wkwebview es6-proxy
1个回答
1
投票

昨天我整天都很愚蠢。我使用的是MutationObserver,并且工作正常。这比需要拦截javascript对象以进行DOM拦截要优越得多。图像对象最终在DOM中插入img标签。将src插入DOM后,我可以立即对其进行更改。但是我不必要地写了Image的包装。删除该包装程序可以很好地完成工作,但可以满足我们拦截和修改src属性的意图。

© www.soinside.com 2019 - 2024. All rights reserved.