如何使用 ES6 代理 ArrayBuffer 或 Uint8Array?

How to ES6 Proxy an ArrayBuffer or Uint8Array?

这些作品:

crypto.subtle.digest('SHA-512', new Uint8Array([0]))
crypto.subtle.digest('SHA-512', new Uint8Array([0]).buffer)

这些没有:

crypto.subtle.digest('SHA-512', new Proxy(new Uint8Array([0]),{}))
crypto.subtle.digest('SHA-512', new Proxy(new Uint8Array([0]).buffer,{})

错误:

Failed to execute 'digest' on 'SubtleCrypto': The provided value is not of type '(ArrayBuffer or ArrayBufferView)'

instanceof Uint8Arrayinstanceof ArrayBuffer return 在这两种情况下都是正确的。

digest is specified by its IDL interface to only accept a BufferSource, which is either an ArrayBufferView or an ArrayBuffer。这种 IDL 级类型表明正确的实现将断然拒绝任何不具有正确内部类型的输入。

您可能想使用 Proxy 的任何技巧都不会在 digest 上起作用。相反,您可以使用代理技巧在将数据传递给 digest.

之前立即获得您想要的确切 ArrayBuffer

例如,这里有一个代理,它伪造了一个 buffer,这个 buffer 不同于其内部对象上的 bufferbuffer 是真实的,所以可以传入 digest,但它是由 Proxy 魔法创建的:

var proxy = new Proxy(new Uint8Array([0]), {
                          get:function(obj, prop) {
                              if(prop=="buffer"){ return new Uint8Array([42]).buffer }
                              else { return obj[prop]; }
                          }
            });
crypto.subtle.digest('SHA-512', proxy.buffer)

如果无法生成缓冲区(例如,如果它太大而无法放入 RAM),您目前将不得不依赖 SubtleCrypto 以外的东西。

这似乎是 W3C 提出的一个很好的观点,例如,支持 update 机制来迭代收集输入。