El módulo de solicitud de Node.js

    En estos días, nuestras aplicaciones web tienden a tener muchas integraciones con otros servicios, ya sea interactuando con un servicio REST como Twitter o descargando imágenes de Flickr. El uso de Node / JavaScript es uno de los lenguajes más populares para manejar aplicaciones como esta. De cualquier manera, realizará muchas solicitudes HTTP, lo que significa que necesitará un módulo sólido para que la escritura del código sea mucho más llevadera.

    los solicitud module es, con mucho, el paquete Node más popular (no estándar) para realizar solicitudes HTTP. En realidad, es solo una envoltura de los componentes integrados de Node http módulo, para que pueda lograr la misma funcionalidad por su cuenta con http, pero request simplemente lo hace mucho más fácil.

    Realización de solicitudes HTTP

    Si bien hay bastantes opciones disponibles en request (muchos de los cuales cubriremos a lo largo de este artículo), también puede ser bastante simple de usar. El ejemplo de «hola mundo» para esta biblioteca es tan fácil como pasar una URL y una devolución de llamada:

    const request = require('request');
    
    request('http://Pharos.sh.com', function(err, res, body) {
        console.log(body);
    });
    

    El código anterior envía una solicitud HTTP GET a Pharos.sh.com y luego imprime el HTML devuelto en la pantalla. Este tipo de solicitud funciona para cualquier punto final HTTP, ya sea que devuelva HTML, JSON, una imagen o casi cualquier otra cosa.

    El primer argumento para request puede ser una cadena de URL o un objeto de opciones. Estas son algunas de las opciones más comunes que encontrará en sus aplicaciones:

    • url: La URL de destino de la solicitud HTTP
    • method: El método HTTP que se utilizará (GET, POST, DELETE, etc.)
    • headers: Un objeto de encabezados HTTP (clave-valor) que se establecerá en la solicitud
    • form: Un objeto que contiene datos de formulario de valor-clave
    const request = require('request');
    
    const options = {
        url: 'https://www.reddit.com/r/funny.json',
        method: 'GET',
        headers: {
            'Accept': 'application/json',
            'Accept-Charset': 'utf-8',
            'User-Agent': 'my-reddit-client'
        }
    };
    
    request(options, function(err, res, body) {
        let json = JSON.parse(body);
        console.log(json);
    });
    

    Utilizando la options objeto, esta solicitud utiliza el método GET para recuperar datos JSON directamente de Reddit, que se devuelve como una cadena en el body campo. Desde aquí, puede usar JSON.parse y utilizar los datos como un objeto JavaScript normal.

    Este mismo formato de solicitud se puede utilizar para cualquier tipo de método HTTP, ya sea DELETE, PUT, POST u OPTIONS. Aunque, no todos los métodos se utilizan exactamente igual. Algunos, como el método POST, pueden incluir datos dentro de la solicitud. Hay algunas formas en que se pueden enviar estos datos, algunas de las cuales son:

    • body: UN Buffer, Stringo Stream objeto (puede ser un objeto si json la opción está configurada en true)
    • form: Un objeto de datos de pares clave-valor (veremos esto más adelante)
    • multipart: Una matriz de objetos que pueden contener sus propios encabezados y atributos de cuerpo

    Cada uno satisface una necesidad diferente (y hay incluso más formas de enviar datos, que se pueden encontrar en esta sección del archivo README de la solicitud). los request Sin embargo, el módulo contiene algunos métodos convenientes que hacen que sea un poco más fácil trabajar con ellos, así que asegúrese de leer los documentos completos para evitar que su código sea más difícil de lo que debe ser.

    Hablando de métodos auxiliares, una forma mucho más sucinta de llamar a los diferentes métodos HTTP es utilizar los respectivos métodos auxiliares proporcionados. Éstos son algunos de los más utilizados:

    • request.get(options, callback)
    • request.post(options, callback)
    • request.head(options, callback)
    • request.delete(options, callback)

    Si bien esto no le ahorrará un montón de líneas de código, al menos hará que su código sea un poco más fácil de entender al permitirle ver el método que se llama y no tener que analizar todas las opciones para encontrar eso.

    Formularios

    Ya sea que esté interactuando con una API REST o creando un bot para rastrear y enviar datos en sitios web, en algún momento deberá enviar datos para un formulario. Como siempre con request, esto se puede hacer de diferentes formas, dependiendo de sus necesidades.

    Para formularios regulares (codificados en URL, con un MÍMICA tipo de application/x-www-form-urlencoded), es mejor que uses el .post() método de conveniencia con el objeto de formulario:

    let options = {
        url: 'http://http://mockbin.com/request',
        form: {
            email: '[email protected]',
            password: 'myPassword'
        }
    };
    
    request.post(options, callback);
    

    Esto cargará datos como lo haría un formulario HTML, con la única limitación de que no puede cargar archivos de esta manera. Para hacer eso, necesita usar el formData en su lugar, que utiliza la formulario-datos biblioteca debajo.

    Utilizando formData en su lugar, ahora podemos pasar datos de archivo al servidor a través de Buffers, Streams, o incluso datos que no son de archivo (como antes) con pares clave-valor simples.

    let formData = {
        // Pass single file with a key
        profile_pic: fs.createReadStream(__dirname + '/me.jpg'),
    
        // Pass multiple files in an array
        attachments: [
            fs.readFileSync(__dirname + '/cover-letter.docx'),  // Buffer
            fs.createReadStream(__dirname + '/resume.docx'),    // Stream
        ],
    
        // Pass extra meta-data with your files
        detailed_file: {
            value: fs.createReadStream(__dirname + '/my-special-file.txt'),
            options: {
                filename: 'data.json',
                contentType: 'application/json'
            }
        },
    
        // Simple key-value pairs
        username: 'ScottWRobinson'
    };
    
    request.post('http://http://mockbin.com/request', {formData: formData}, callback);
    

    Esto enviará sus archivos con un tipo MIME de multipart/form-data, que es una carga de formulario de varias partes.

    Si bien esto será más que suficiente para la mayoría de los casos de uso de los usuarios, hay ocasiones en las que necesita un control aún más detallado, como CLRF (nuevas líneas) pre / post, fragmentación o especificar sus propias partes múltiples. Para obtener más información sobre estas opciones adicionales, consulte esta sección del request LÉAME.

    Corrientes

    Una de las características más infrautilizadas en muchos lenguajes de programación, en mi opinión, son las transmisiones. Su utilidad se extiende más allá de las solicitudes de red, pero esto sirve como un ejemplo perfecto de por qué debería usarlas. Para obtener una breve descripción sobre cómo y por qué debería usarlos, consulte la sección «Flujos» del artículo Servidores HTTP de node para el servicio de archivos estáticos.

    En resumen, el uso de transmisiones para grandes cantidades de datos (como archivos) puede ayudar a reducir la huella de memoria de su aplicación y el tiempo de respuesta. Para hacer esto más fácil de usar, cada uno de los request los métodos pueden pipe su salida a otra corriente.

    En este ejemplo, descargamos el logotipo de Node.js mediante una solicitud GET y lo transmitimos a un archivo local:

    let fileStream = fs.createWriteStream('node.png');
    request('https://nodejs.org/static/images/logos/nodejs-new-white-pantone.png').pipe(fileStream);
    

    Tan pronto como la solicitud HTTP comience a devolver partes de la imagen descargada, «canalizará» esos datos directamente al archivo «node.png».

    Descargar un archivo de esta manera también tiene otros beneficios. Las transmisiones son excelentes para aplicar transformaciones en los datos a medida que se descargan. Por ejemplo, digamos que está descargando una gran cantidad de datos confidenciales con request que debe cifrarse de inmediato. Para hacer esto, puede aplicar una transformación de cifrado canalizando la salida de request a crypto.createCipher:

    let url="http://example.com/super-sensitive-data.json";
    let pwd = new Buffer('myPassword');
    
    let aesTransform = crypto.createCipher('aes-256-cbc', pwd);
    let fileStream = fs.createWriteStream('encrypted.json');
    
    request(url)
        .pipe(aesTransform)     // Encrypts with aes256
        .pipe(fileStream)       // Write encrypted data to a file
        .on('finish', function() {
            console.log('Done downloading, encrypting, and saving!');
        });
    

    Es fácil pasar por alto las transmisiones, y muchas personas lo hacen cuando escriben código, pero pueden ayudar bastante a tu rendimiento, especialmente con una biblioteca como request.

    Misc. Configuraciones

    Las solicitudes HTTP implican mucho más que simplemente especificar una URL y descargar los datos. Para aplicaciones más grandes, y especialmente aquellas que deben admitir una gama más amplia de entornos, es posible que sus solicitudes deban manejar bastantes parámetros de configuración, como proxies o certificados de confianza SSL especiales.

    Un misceláneo importante. característica a señalar es la request.defaults() , que le permite especificar parámetros predeterminados para que no tenga que proporcionarlos para cada solicitud que realice.

    let req = request.defaults({
        headers: {
            'x-access-token': '123abc',
            'User-Agent': 'my-reddit-client'
        }
    });
    
    req('http://your-api.com', function(err, res, body) {
        console.log(body);
    });
    

    Ahora, en el ejemplo anterior, todas las solicitudes realizadas con req siempre tendrá los encabezados x-access-token y User-Agent conjunto. Esto es ideal para configurar encabezados como estos, servidores proxy o configuraciones TLS / SSL.

    A lo largo del resto de esta sección, veremos algunas características más comunes que encontrará:

    Proxies

    Ya sea que su computadora esté detrás de un proxy corporativo o desee redirigir su tráfico a otro país, en algún momento es posible que deba especificar una dirección de proxy. La forma más sencilla de lograrlo es utilizar el proxy opción, que toma una dirección en la que el tráfico se transfiere a través de:

    let options = {
        url: 'https://www.google.com',
        proxy: 'http://myproxy.com'
    };
    
    request(options, callback);
    

    los options object es una forma de especificar un proxy, pero request también utiliza las siguientes variables de entorno para configurar una conexión proxy:

    • HTTP_PROXY / http_proxy
    • HTTPS_PROXY / https_proxy
    • NO_PROXY / no_proxy

    Esto le brinda un poco más de control, como configurar qué sitios no deben ser proxiados a través del NO_PROXY variable.

    TLS / SSL

    A veces, una API necesita tener algo de seguridad adicional y, por lo tanto, requiere un certificado de cliente. En realidad, esto es bastante común con las API corporativas privadas, por lo que vale la pena saber cómo hacerlo.

    Otro escenario posible es que desee que sus solicitudes HTTP confíen explícitamente en ciertos autoridades de certificación, que podría incluir certificados autofirmados por usted o su empresa.

    Al igual que con todas las otras configuraciones que hemos visto hasta ahora, estas se establecen en el options objeto:

    const fs = require('fs');
    const request = require('request');
    
    let myCertFile = fs.readFileSync(__dirname + '/ssl/client.crt')
    let myKeyFile = fs.readFileSync(__dirname + '/ssl/client.key')
    let myCaFile = fs.readFileSync(__dirname + '/ssl/ca.cert.pem')
     
    var options = {
        url: 'https://mockbin.com/request',
        cert: myCertFile,
        key: myKeyFile,
        passphrase: 'myPassword',
        ca: myCaFile
    };
     
    request.get(options);
    
    Autenticación básica

    Sitios que utilizan autenticación de acceso básico todavía se puede acceder utilizando el auth opción:

    const request = require('request');
     
    var options = {
        url: 'https://mockbin.com/request',
        auth: {
            username: 'ScottWRobinson',
            password: 'myPassword'
        }
    };
     
    request.get(options);
    

    Esta opción establece uno de los encabezados HTTP como "authorization": "Basic c2NvdHQ6cGFzc3dvcmQh". La cadena ‘Básica’ en el encabezado ‘autorización’ declara que se trata de una solicitud de autenticación básica y la cadena alfanumérica que sigue es una codificación RFC2045-MIME (una variante de Base64) de nuestro nombre de usuario y contraseña.

    Redireccionamientos

    Descubrí que en algunas aplicaciones, como el raspado web, hay bastantes casos en los que es necesario seguir las redirecciones para que su solicitud sea exitosa. Como probablemente adivinó, hay una opción para especificar si se deben seguir las redirecciones de forma predeterminada, pero request va incluso un paso más allá y le permitirá proporcionar una función que se puede utilizar para determinar condicionalmente si se debe seguir la redirección.

    Algunas de las opciones de redireccionamiento son:

    • followRedirect: Si true, luego siga todas las redirecciones HTTP 3xx. O envíe un function(res) {} que se utiliza para determinar si se debe seguir o no el redireccionamiento
    • followAllRedirects: Siga todos los redireccionamientos HTTP 3xx que no sean GET
    • maxRedirects: El número máximo de veces que se deben seguir los redireccionamientos encadenados (el valor predeterminado es 10)

    Conclusión

    Sin duda request es un módulo poderoso y probablemente uno que usará con frecuencia. Dadas todas las características que proporciona, puede actuar como un excelente punto de partida para cualquier cosa, desde un rastreador web hasta una biblioteca cliente para su API.

    Hay bastantes opciones y configuraciones más que se pueden utilizar con request de lo que hemos mostrado aquí, así que asegúrese de revisar el documentación para más detalles. Tenga en cuenta que no todo en el módulo está documentado, por lo que es posible que deba hacer más búsquedas / experimentos para encontrar la respuesta.

    Has usado request en alguno de tus proyectos? ¿Si es así, cómo?

     

    Etiquetas:

    Deja una respuesta

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *