【问题标题】:Native Image object proxy in javascriptjavascript中的本机图像对象代理
【发布时间】: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 解决了这个问题。我会回复它。再次感谢您对此进行调查。

标签: wkwebview es6-proxy


【解决方案1】:

我昨天一整天都这么傻。我使用的是MutationObserver,它工作正常。这比任何需要拦截 DOM 拦截的 javascript 对象要优越得多。 Image 对象最终会在 DOM 中插入 img 标签。我可以在将 src 插入 DOM 后立即更改它。但是我不必要地写了一个 Image 的包装器。删除该包装器可以很好地工作,但满足我们拦截和修改 src 属性的意图。

【讨论】:

    猜你喜欢
    • 2021-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多