#代理模式

#科学上网

VPN(虚拟专用网络)

为了屏蔽某些网站,一股神秘的东方力量会作用于你的 DNS 解析过程,告诉它:“你不能解析出 xxx.xxx.xxx.xxx(某个特殊 ip)的地址”

代理服务器是第三方的未禁用的 ip,代理服务器访问目标网站后返回响应体

#生产实践

#事件代理

一个父元素下有多个子元素,由父元素对事件进行处理和分发、间接地将其作用于子元素,因此这种操作从模式上划分属于代理模式

// 获取父元素
const father = document.getElementById('father')

// 给父元素安装一次监听函数
father.addEventListener('click', function (e) {
  // 识别是否是目标子元素
  if (e.target.tagName === 'A') {
    // 以下是监听函数的函数体
    e.preventDefault()
    alert(`我是${e.target.innerText}`)
  }
})

#虚拟代理

使用虚拟占位图片代理真实图片

class PreLoadImage {
  constructor(imgNode) {
    // 获取真实的DOM节点
    this.imgNode = imgNode
  }

  // 操作img节点的src属性
  setSrc(imgUrl) {
    this.imgNode.src = imgUrl
  }
}

class ProxyImage {
  // 占位图的url地址
  static LOADING_URL = 'xxxxxx'

  constructor(targetImage) {
    // 目标Image,即PreLoadImage实例
    this.targetImage = targetImage
  }

  // 该方法主要操作虚拟Image,完成加载
  setSrc(targetUrl) {
    // 真实img节点初始化时展示的是一个占位图
    this.targetImage.setSrc(ProxyImage.LOADING_URL)
    // 创建一个帮我们加载图片的虚拟Image实例
    const virtualImage = new Image()
    // 监听目标图片加载的情况,完成时再将DOM上的真实img节点的src属性设置为目标图片的url
    virtualImage.onload = () => {
      this.targetImage.setSrc(targetUrl)
    }
    // 设置src属性,虚拟Image实例开始加载图片
    virtualImage.src = targetUrl
  }
}

#缓存代理

代理来帮我们在进行计算的同时,进行计算结果的缓存了

如 ahooks 的 useRquest 的 cacheKey

在发起请求前进行代理,如果有缓存,则使用缓存的数据,否则发起请求并缓存

通过缓存函数代理

#保护代理

ES6 中的 Proxy

通过 Proxy 拦截访问

var obj = { a: 1 }
var handler = {
  get: function (target, prop, receiver) {
    console.log(target, prop, receiver)
    return 42
  },
}

var p = new Proxy(obj, handler)
console.log(p.a) // 42

#小结

A 不能直接访问 B,A 需要借助一个帮手来访问 B,这个帮手就是代理器