前端拦截Image的src并返回原生对象

您所在的位置:网站首页 js拦截请求并修改url 前端拦截Image的src并返回原生对象

前端拦截Image的src并返回原生对象

2024-01-21 12:03| 来源: 网络整理| 查看: 265

做框架的时候因为跨域问题,需要将用户的请求目标进行hook,拦截用户代码的Image.src操作并重定向到自己的url进行代理访问。为此进行了一些研究。

可能的解决方案 利用Proxy包装并返回Proxy,通过handler拦截。利用Object.defineProperty监听变化并拦截

利用Proxy方法拦截有个弊端,由于返回的是Proxy对象,虽然能够拦截src并进行修改,但是将无法通过drawImage绘制到Canvas上。

正常的绘制方法:

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

加了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 }

虽然更改了src但无法绘制到canvas上,我的解决办法是利用Object.defineProperty,同时保存原有的setter来保持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成功 }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3