El front-end intercepta el src de la imagen y devuelve el objeto nativo

Al crear un marco, debido a problemas entre dominios, es necesario enlazar el destino de la solicitud del usuario, interceptar la operación Image.src del código del usuario y redirigirlo a su propia URL para acceso de proxy. Investigué un poco sobre esto.

solución posible

  • Use Proxy para envolver y devolver Proxy, e interceptarlo a través del controlador.
  • Use Object.defineProperty para monitorear cambios e interceptar

Hay una desventaja de usar el método Proxy para interceptar, dado que se devuelve el objeto Proxy, aunque el src se puede interceptar y modificar, no podrá dibujar en el lienzo a través de drawImage.

Método de dibujo normal:

let canvas2d = document.createElement('canvas').getContext('2d')
let img = new Image()
image.src='a.jpg'
// image会自动请求
image.onload = ()=>{
    
    
  canvas2d.drawImage(img,0,0)
  // 成功绘制
}

Después de agregar la interceptación de Proxy:

function hookFunction(src){
    
    
  // hook的url
}
function FakeImage(){
    
    
  const img = new Image()
  const handler = {
    
    
    set(obj, prop, value) {
    
    
    if ((prop === 'src')) {
    
    
      console.log('Hook set src',value);
      obj[prop] = hookFunction(src)
    } else {
    
    
      return Reflect.set(...arguments);
    }
  }
  }
  return new Proxy(img,handler)
}

let canvas2d = document.createElement('canvas').getContext('2d')
let img = new FakeImage()
image.src='a.jpg'
// image会自动请求
image.onload = ()=>{
    
    
  canvas2d.drawImage(img,0,0)
  // 绘制出错,img为Proxy对象,不是HTMLImageElement
}

Aunque se ha cambiado el src, no se puede dibujar en el lienzo.Mi solución es usar Object.defineProperty mientras se guarda el setter original para mantener la solicitud automática de HTMLImageElement.

function hookFunction(src){
    
    
  // hook的url
}
function FakeImage(){
    
    
  const img = new Image()

  // 保存原有的setter
  const originalSet = Object.getOwnPropertyDescriptor(img.__proto__,'src').set

  Object.defineProperty(img,'src',{
    
    
    set:(src)=>{
    
    
      console.log('Hook set src',value)
      // call原来的setter以触发自动请求
      originalSet.call(img,value)
    }
  })
  return img
}

let canvas2d = document.createElement('canvas').getContext('2d')
let img = new FakeImage()
image.src='a.jpg'
// image会自动请求
image.onload = ()=>{
    
    
  canvas2d.drawImage(img,0,0)
  // 绘制成功且hook成功
}

Supongo que te gusta

Origin blog.csdn.net/weixin_43192572/article/details/118345997
Recomendado
Clasificación