代理模式
-
模式定义
代理模式 给某一个对象提供一个代理对象,并由代理对象控制对原对象的访问
通俗的理解就是
我们生活中常见的中介通过原生
JS的Proxy可以实现该设计模式 -
模式作用
对被代理的对象进行拦截,当被代理对象被访问时可以实现统一的处理
增强代码的
高扩展性 -
生活示例
假如我想买一辆二手车,虽然我可以自己去找车源,做质量检测等一系列的车辆过户流程,但是这太浪费我得时间和精力
我只是想买一辆车而已,为什么还要额外做这么多事情呢?于是我就通过中介公司来买车,他们给我找车源,帮我办理车辆过户流程等,我只负责选择自己喜欢的车,然后付钱就可以了
封装 fetch 请求
-
工具方法
判断 FormData 类型const isFormData = (val) => { return (typeof FormData !== 'undefined') && (val instanceof FormData) }将对象转为查询参数const queryString = (data = {}) => { return Object.keys(data).map(key=>`${encodeURIComponent(key)}=${encodeURIComponent(data[key])}`).join('&') } -
请求策略
const configPolicy = Object.assign(Object.create(null), { GET({ url, data = {}, ...config } = options) { const params = queryString(data) return Object.assign(config, { url: params ? `${url}?${params}` : url, }) }, POST({ data = null, payloadType = 'json', headers = {}, ...config } = options) { const payload = data || (payloadType === 'json' ? JSON.stringify(data) : queryString(data)) return Object.assign(config, { body: payload, headers: { ...headers, 'Content-Type': payloadType == 'urlencoded' ? 'application/x-www-form-urlencoded; charset=utf-8' : 'application/json; charset=utf-8' } }) } }) -
策略匹配
const fetch2 = async ({ prefix = '/api', method, ...options }) => { Object.assign(options, { method: method ? method.toUpperCase() : 'POST' }) if (isFormData(options.data) && options.method == 'POST') { const { url, data, ...config } = options config.body = data return await fetch(`${prefix}${url}`, config) } else { const { url, ...config } = configPolicy[options.method](options) return await fetch(`${prefix}${url}`, config) } } -
代理拦截
const handler = { async apply(target, ctx, [config = {}] = args) { const token = localStorage.getItem('AUTH-TOKEN') Object.assign(config, { 'headers': { 'Authorization': token, } }) const res = await Reflect.apply(...arguments) if (res.ok) { const { state, msg = null, obj: data = null } = await res.json() return { state, msg, data } } throw new Error(res.statusText) } } const proxyFetch2 = new Proxy(fetch2, handler) -
注意事项
GET请求忽略Content-Type配置,直接将参数拼接至请求URL上即可POST请求传输FormData类型数据时,需要删除请求头的Content-Type配置,让浏览器自己适配,否则会造成数据传输失败一起学习,加群交流看 沸点