Red de conocimiento informático - Aprendizaje de programación - ¿Qué cosas interesantes pueden hacer los servidores proxy de JavaScript?

¿Qué cosas interesantes pueden hacer los servidores proxy de JavaScript?

Qué es un agente

Antes que nada, aclaremos qué es un agente. La palabra se traduce como agencia.

Se puede entender que hay una estrella muy popular que ha abierto una cuenta de Weibo. Esta cuenta es muy activa, responde a los fans, da me gusta en todas partes, etc., pero es posible que realmente no la mantenga. a él.

Pero hay una persona o un equipo detrás de esto. Podemos llamarlos agentes, porque el Weibo que publican representa a la propia estrella.

P.D. Como no sigo a celebridades, solo estoy dando ejemplos, pero supongo que podría existir un equipo así.

Esto se puede interpretar en JavaScript como una referencia a un objeto o función Operación del agente.

Proxies en JavaScript

Los proxies son una nueva API proporcionada por ES6 que se puede usar para definir comportamientos personalizados para varias operaciones básicas en objetos (llamadas trampas en la documentación, creo). (lo usa como gancho para varios comportamientos de un objeto), puede usarse para hacer muchas cosas interesantes y será una herramienta útil para controlar el comportamiento de un objeto.

Sintaxis de proxy

Para crear una instancia de proxy, debe pasar dos parámetros

1. El objeto de destino que se va a representar puede ser un objeto o una función.

2. Controladores, utilizados para manejar diversos comportamientos operativos de objetos proxy

let target = {}

let handlers = {}

2.// No hacer nada

let proxy = new Proxy(destino, controladores)

proxy.a = 123

console.log (target.123

En el caso de que el segundo parámetro sea un objeto vacío, básicamente se interpreta como una copia superficial del primer parámetro

(el proxy debe ser una copia de capa superficial, si es así). una copia profunda, el significado del agente se pierde)

Trampa (agente para varios comportamientos)

Al igual que el código de muestra anterior, si la trampa no está definida, no se puede hacer nada. hecho, que es lo mismo que operar directamente el objetivo.

Cuando escribimos una trampa, nuestra función de devolución de llamada se activará cuando realicemos la operación correspondiente, controlando así el comportamiento del objeto proxy. p>

Las dos trampas más comunes son get y set

Los primeros JavaScript tenían una forma de configurar captadores y definidores de propiedades al definir el objeto:

let obj = {

_age:18,

obtener edad () {

return `Tengo ${this._age} años`

},

establecer edad (val) {

this._age = Número(val)

}

}

console.log(obj.age) // Tengo 18 años

obj.age = 19

console.log(obj .age) // / / Tengo 18 años

obj.age = 19

console.log(obj.age) // // Tengo 18 años })()

Estamos representando el get y ejecutando la lógica internamente, por lo que si queremos obtener un valor de una clave que no existe, crearemos la clave correspondiente en el destino y devolveremos ese agente clave.

Esto asegurará que no obtengamos xxx de un valor indefinido

Pero hay un pequeño defecto: si realmente deseas determinar si la clave existe, solo puedes usar el operador en operación en lugar del operador get.

Compatibilidad entre funciones ordinarias y constructores

Si proporcionamos un objeto de clase, o la versión ES5 del constructor, a otros.

Si no se utiliza la nueva palabra clave al llamar, el objeto Clase solo generará una excepción y el constructor que apunta al constructor en ES5 se convertirá en el alcance de la función llamada.

Podemos aplicar esta trampa para lidiar con esta situación:

clase Prueba {

constructor (a, b) {

consola .log('constructor', a, b)

}

}

}

}

// Prueba(1, 2) // Genera un error

let proxyClass = new Proxy(Test, {

apply (target, thisArg.argumentsList) {

Consola, lista de argumentos) {

// Si desea evitar llamar a una función de una manera no nueva, simplemente lanza una excepción

// lanza un nuevo Error(`Función ${ target.name} no se puede llamar sin 'new'`)

return new (target.bind(thisArg, .argumentsList))()

}

})

proxyClass(1, 2) //Constructor 1 2

Usamos aplicar para proxy algunos comportamientos que se activan cuando se llama a la función, porque conocemos claramente el proxy Es una clase o constructor, por lo que usamos directamente la nueva palabra clave en apply para llamar a la función del agente.

Además, si queremos restringir la función para prohibir llamadas con la nueva palabra clave, podemos usar otra trampa: construct

función add (a, b) {

devolver un b

}

let proxy = new Proxy( add, {

construct (target, argumentsList, newTarget) {

throw new Error(`La función ${target.name} no se puede llamar con 'new'`)

}

})

proxy(1 , 2 ) // 3

nuevo proxy(1, 2) // Error de activación

Usar proxy para encapsular fetch

El envío de solicitudes en el front-end es Lo que usamos a menudo ahora es la función Fetch, una API proporcionada localmente.

let handlers = {

get (objetivo, propiedad) {

if (!target.init) {

//Inicialización Objeto

['GET', 'POST'].forEach(método =gt; {

objetivo[método] = (url, params = {}) =gt; {

return fetch(url, {

encabezados: {

'tipo de contenido': 'aplicación/json'

}, }

modo: 'cors',

credenciales: 'mismo origen',

método,

... .params

}).then(respuesta =gt; respuesta.json())

}

})

}

}

return target[property]

}

}

let API = new Proxy({}, handlers)

esperar API.GET('XXX')

esperar API.POST('XXX', {

cuerpo: JSON.stringify({nombre: 1 })

})

Una capa de encapsulación de GET y POST, que se puede llamar directamente a través de .GET y establecer algunos parámetros comunes.

Implementación de una herramienta de aserción simple

Todos los que hayan escrito pruebas deben entender las aserciones

console.assert es una herramienta de aserción que acepta dos parámetros, si el primer parámetro es falso, arrojará el segundo parámetro como un mensaje de error.

Podemos utilizar proxies para crear una herramienta que realice afirmaciones por asignación directa.

let afirmar = new Proxy({}, {

set (destino, mensaje, valor) {

if (!value) console.error(message )

}

})

afirmar['Isn\'t true'] = false // Error: No es cierto

assert['Mess than 18'] = 18 gt; = 19 // Error: menos de 18

Cuenta el número de llamadas a funciones

Al realizar el lado del servidor, puedo usar un proxy Para proxy ciertas funciones para contar el número de llamadas durante un período de tiempo.

Podemos usarlo en futuros análisis de rendimiento:

function orginFunction () {}

let proxyFunction = new Proxy(orginFunction, {

p>

aplicar (destino, thisArg. argumentsList. thisArg. argumentsList) {

log(XXX)

return target.apply(thisArg, argumentsList)

}

})

Todas las trampas

Aquí hay una lista de todos los comportamientos (trampas) que se pueden definir para los controladores:

Ver MDN-Agent

Obtener valor clave

Configuración

Obtener valor clave

Obtener valor clave

Obtener el valor clave

Establecer

Establecer el valor clave

tiene

Utilice el operador in para determinar si la clave existe

aplicar

Llamada a función, solo válida cuando el proxy es una función

ownKeys

Obtener todas las claves del objetivo

construcción

construcción

construcción

construcción

construcción

construcción

construcción

construcción

construcción

construcción

construcción

Una función llamada a través de creación de instancias, solo válido cuando el proxy es una función

isExtensible

Determina si el objeto es extensible, el proxy del objeto. esExtensible

eliminarProperty