proxy代理服务

Posted 勇敢*牛牛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了proxy代理服务相关的知识,希望对你有一定的参考价值。

Proxy代理服务

面试题:

var item = 
var p = new Proxy(item,
    set(target,key,value)
        // target : 是这个代理对象,key是属性,value是属性值
        if(value<0 || value >99) throw new RangeError("当前设置超出范围");
        target[key] = value;
    ,
    get(target,key)
        target[key]++;
        return target[key];
    
)
p.o = 12;
console.log(item);
console.log(p.o);//13
console.log(p.o);//14
console.log(p.o);//15
console.log(p.o==16 && p.o==17 && p.o==18)//true

生成一个div盒子

var divs = new Proxy(div,
    set(target,key,value)
        if(/width|heigh/.test(key) && !/px$/.test(value)) value+="px";
        target.style[key] = value;
    
)
divs.width = 500;
divs.height=50;
divs.backgroundColor = "red"

用法
Proxy 为构造函数,用来生成 Proxy 实例

var proxy = new Proxy(target, handler);

上面的代码,new Proxy() 生成一个 Proxy 实例,target 参数表示所要拦截的目标对象,handler 参数也是一个对象,用来指定拦截行为;
一个简单的示例:

const person = 
	name: "赵云",
	age: 21


const proxy = new Proxy(person, 
	get: function(target, propKey) 
		console.log(target);
		console.log(propKey);
		return target[propKey];
	
);

// name: '赵云', age: 21
// name
// 赵云
console.log(proxy.name);

上面的代码,创建了一个 person 对象,它有两个属性,分别为 name 和 age; 实例化了一个 Proxy ,将 person 作为第一个参数(所要拦截的目标对象),第二个传入的参数是一个对象,它有一个 get 属性,值是一个回调函数;

Proxy 支持的拦截操作
实例化 Proxy 的第二个参数是一个对象,其中可以指定 Proxy 支持的拦截操作;对几种常见的拦截操作进行举例说明;

get(target, propKey, receiver)
get 方法用于拦截某个属性的读取操作;
get 方法接收三个参数,目标对象、属性名、proxy 实例本身(操作行为所针对的对象);最后一个参数是可选的;
示例:

const person = 
	name: "赵云"


const proxy = new Proxy(person, 
	get: function(target, propKey) 
		if (propKey in target) 
			return target[propKey];
		 else 
			throw new ReferenceError(`属性名$propKey不存在`);
		
	
);

console.log(proxy.name);    // 赵云
console.log(proxy.age);     // Uncaught ReferenceError: 属性名age不存在
set(target,propKey,value,receiver)

set 方法用来拦截某个属性的赋值操作;
set 方法接收四个参数,目标对象、属性名、属性值和 Proxy 实例本身;最后一个参数是可选的;
示例:
假定 Person 对象有一个 age 属性,该属性应该是一个不大于 200 的整数,那么可以使用 Proxy 保证 age 的属性值符合要求;

const person = 
	age: 20


// 年龄大于 200 报错
const proxy = new Proxy(person, 
	set: function(target, propKey, propValue) 
		if (propKey === 'age') 
			if (!Number.isInteger(propValue)) 
				throw new ReferenceError(`age 不是一个整数`);
			else if (propValue > 200) 
				throw new ReferenceError(`age 不能超过200`);
			
		

		// 满足条件的 age 及其他属性,直接保存
		target[propKey] = propValue;
		return true;
	
);
proxy.age = 28;

console.log(proxy.age);         // 28
console.log(proxy.age = "28");  // Uncaught ReferenceError: age 不是一个整数
console.log(proxy.age = 288);   // Uncaught ReferenceError: age 不能超过200
let api = 
	_apiKey: "123abc456def",
	getUser: function(userId) ,
	setUser: function(userId, config) 


console.log(api._apiKey);   // 此处可用
const restricted = ['_apiKey'];
api = new Proxy(api, 
	set: function(target, propKey, propsValue, proxy) 
		if (restricted.indexOf(propKey) > -1) 
			throw Error(`$propKey 不可访问`);
		
		return Reflect.set(target, propKey, propsValue, proxy);
	,

	get: function(target, propKey, proxy) 
		if (restricted.indexOf(propKey) > -1) 
			throw Error(`$propKey 不可访问`);
		
		return Reflect.get(target, propKey, proxy);
	
);

// 一下操作都会抛出错误
api._apiKey;
api._apiKey = "123";

预警,拦截,过滤
实现观察者模式
服务端代理,跨域,取消请求等

以上是关于proxy代理服务的主要内容,如果未能解决你的问题,请参考以下文章

ES6的Proxy

Flag配送中心(CVE-2016-5385)

Flag配送中心(CVE-2016-5385)

前端开发服务器中的 Proxy 代理跨域实现原理解读

es6之proxy学习

es6之proxy学习