如何拦截image.src赋值并在资源请求前修改路径?
拦截资源元素的src赋值并处理URL
针对你遇到的直接通过src加载图片、音视频的场景,可以通过重写元素原型的属性描述符来拦截赋值操作,在实际请求前修改URL。以下是几种可行方案:
1. 针对单一元素类型(如Image)重写src setter
直接修改HTMLImageElement原型的src属性,所有通过new Image()或页面中已有的<img>元素设置src时都会触发拦截:
// 保存原始的src属性描述符 const originalImageSrc = Object.getOwnPropertyDescriptor(HTMLImageElement.prototype, 'src'); // 重写src的setter Object.defineProperty(HTMLImageElement.prototype, 'src', { set(value) { // 执行URL替换逻辑 const modifiedUrl = value.replace("www.somewhere", "www.elsewhere"); // 调用原始setter完成赋值 originalImageSrc.set.call(this, modifiedUrl); }, get() { // 保留原始getter行为 return originalImageSrc.get.call(this); }, configurable: true, enumerable: true });
如果需要处理视频、音频,只需将HTMLImageElement替换为HTMLVideoElement或HTMLAudioElement,重复上述逻辑即可。
2. 通用拦截所有媒体元素的src
如果要一次性覆盖img、video、audio等所有带src的媒体元素,可以直接修改Element原型的src属性,并通过标签名过滤目标元素:
const originalElementSrc = Object.getOwnPropertyDescriptor(Element.prototype, 'src'); if (originalElementSrc) { Object.defineProperty(Element.prototype, 'src', { set(value) { // 只处理指定类型的元素 const targetTags = ['IMG', 'VIDEO', 'AUDIO']; if (targetTags.includes(this.tagName)) { value = value.replace("www.somewhere", "www.elsewhere"); } originalElementSrc.set.call(this, value); }, get() { return originalElementSrc.get.call(this); }, configurable: true, enumerable: true }); }
注意事项
- 确保拦截代码在所有创建元素或设置src的业务代码之前执行,否则已经初始化的元素不会受影响。
- 字符串替换逻辑可以根据实际需求优化,比如使用
URL对象解析后修改hostname,避免因路径中包含相同字符串导致误替换:const url = new URL(value, window.location.origin); if (url.hostname === 'www.somewhere.com') { url.hostname = 'www.elsewhere.com'; } const modifiedUrl = url.toString();
内容的提问来源于stack exchange,提问作者resle
相关产品推荐
相关产品推荐

