Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Tabla de contenido
1. Introducción a buscar()
2. Obtener JSON
3. Manejo de errores de recuperación
4. Cancelación de una solicitud de recuperación
5. Solicitudes de recuperación paralelas
6. Resumen
1. Introducción a buscar()
La API Fetch accede a los recursos a través de la red. Puede realizar solicitudes HTTP
(utilizando GETy POSTotros métodos), descargar y cargar archivos.
fetch() una solicitud y devuelve una promesa. Cuando se completa la solicitud, la promesa se resuelve con el
objeto Respuesta . Si la solicitud falla debido a algunos problemas de red, se rechaza la promesa.
El método fetch()
El método fetch de la nueva API fetch busca y trae recursos como datos, imágenes etc. . . de
otros archivos ( fetch significa ir a buscar algo, traer algo ).
Un ejemplo básico: utilizar la función fetch para traer una imagen .jpg y mostrarla en pantalla.
funcionAsincrona(url)
// en el caso de exito
.then(console.log("ya tengo la imagen!!"))
// en caso de error
.catch(error =>{console.error(error)})
Con la llegada del es6 para javascript, surgieron nuevas características que facilitaron el uso del
lenguaje en tareas que anteriormente hicieron a muchos desarrolladores orientarse por
utilizar JQuery, como las peticiones HTTP, sin embargo ha pasado el tiempo y las webapps
modernas necesitan nuevas herramientas potentes, y esa es la razón para mirar hacia Fetch API,
tanto así probablemente no necesites más de Jquery ni de axios ni de ninguna otra herramienta
más al terminar de leer esta entrada, así que acomódate bien y acompáñame en las siguientes
líneas donde detallaré todo este tema.
Tiempos memoriales de XMLHttpRequest
Recuerdo que hace algunos años, solo tenias dos opciones para hacer peticiones HTTP,
eran XMLHttpRequest puro y duro o solicitudes AJAX de JQuery para abreviar el mismo
proceso, pero es más, incluso habían y hay aún desarrolladores que realizan el siguiente proceso:
primero aprenden a realizar peticiones utilizando XHR y luego debido a la simplicidad decían:
"para ya no demorar mejor JQuery", y sabes que...en parte tienen razón, porque en muchos casos
es necesario realizar un proyecto de forma rápida, o para un prototipo que no necesita mayor
complicación, pero en otros casos donde la performance y peso de la aplicación es importante
pensando a largo plazo, es mejor evitar utilizar todo el paquete completo que trae JQuery.
Pero como ningún mal dura 100 años, ahora tenemos disponible a Fetch API, una característica
que viene a aportar cosas interesantes, continuemos...
Fetch API
Básicamente es una API de javascript que a través de su interfaz te permite realizar peticiones
HTTP para obtener recursos de la red, globalmente expone un objeto del lado del navegador
llamado fetch. Déjame contarte que desde el inicio, cuando recién salió en forma experimental
ésta característica se notó flexible, esto empezó a llamar la atención de gran cantidad de
desarrolladores, y luego con el paso del tiempo, con multiples cambios realizados a lo largo de los
años se ha vuelto más robusta.
Buenas pregunta, sin embargo cuando miramos las comparaciones puedes tener datos
sumamente reveladores.
Comparación fetch vs axios vs request
Si bien la mayoría de las características están disponibles también en sus competidores directos
(axios y request ), la gran ventaja de fetch es que no necesitas agregar ninguna dependencia de
terceros para poder hacer lo mismo...entonces...¿tú que eliges?... te dejo con esa pregunta mente,
ahora vamos a meter las manos en la masa.
1. Realizas la solicitud.
3. El objeto response es leído a través de funciones según el tipo de dato (json, blob, text, etc.).
fetch(url) // 1
.then(response => response.json()) // 2
.then(console.log) // 3
La ventaja de utilizar promesas es que estas nos permiten encadenarlas, de tal forma que el
resultado de una promesa es pasado como parámetro hacia la siguiente promesa, a menos que se
produzca un error y se pase directamente hacia una función catch(), con eso en mente tenemos las
siguientes instrucciones:
Ejemplo básico
Bien, ahora materializamos el ejemplo realizando una solicitud super básica hacia la API
de jsonplaceholder.
fetch('https://jsonplaceholder.typicode.com/todos/1') // 1
.then(console.log); // 3
Ejemplo básico
2. La promesa es resuelta gracias al then(), que tiene una función espera un objeto Response, y ese
objeto nos permite usar la función json() para resolver la data que viene en ese formato (esa función
devuelve una promesa - otra vez).
Aquí es donde inicia la magia y fetch provee una forma de configurar fácilmente las opciones que
necesitas asignar para realizar tus peticiones, muchos de estos son opcionales según el tipo de
solicitud, veamos algunas:
headers: Cabeceras que se envían en la solicitud, aquí puedes ingresar un objeto e incluso una
instancia de Headers.
body: Datos para enviar en la solicitud, pueden ser un blob, un buffer, form data, string,
etc...considera que las solicitudes GET y HEAD no utilizan esta opción.
Es la petición más básica que debes aprender a realizar, este tipo de peticiones es utilizada para
obtener información, el siguiente ejemplo trae una lista de objetos:
fetch('https://jsonplaceholder.typicode.com/todos')
fetch("https://reqres.in/api/users", {
method: "POST",
})
.then(console.log);
Nótese que hemos agregado la key body, es allí donde podemos agregar la data que se enviara al
server, en este caso en particular está todo ok y la API nos devuelve como respuesta un objeto
ficticio.
Cuando realizas una petición es muy común que necesites personalizar la cabecera, y fetch te
permite hacerlo de una manera super simple utilizando una instancia de Header, veamos:
const customHeaders = new Headers({
});
/*
const customHeaders = {
};
*/
fetch('https://jsonplaceholder.typicode.com/todos', {
headers: customHeaders
})
.then(console.log);
Como puedes ver estamos simulando realizar la petición desde un playstation, pero aún mas
importante que eso es que puedes utilizar un objeto literal para construir un header, ¿genial no?
Enviando un form data con fetch
Este es un caso super utilizado y que con seguridad tú también lo necesitarás en algún momento
de tu vida como desarrollador, el diferencial aquí es el dato que enviamos al backend en el body
de las opciones.
formData.append('website', 'elsitesin.site');
formData.append('action', 'follow');
fetch('urldeapi/create', {
method: 'POST',
})
.then(console.log);
Esta forma de enviar información se utiliza cuando envías por ejemplo una imagen, un video o
incluso solo texto cuando tienes la información dentro de la etiqueta form, lo bueno de todo es
que FormData te permite apilar la información en forma de clave y valor.
Ahora, quizás de has dado cuenta de que no estamos especificando el tipo de contenido que
enviamos, es decir el Content-Type, la razón en este caso puntualmente es que no es necesario,
porque es agregado automáticamente al header, el tipo de contenido viaja como
"multipart/form-data".
Enviando credenciales en fetch
Este es un caso de uso de igual forma de común cuando necesitas identificar a tus usuarios, por
fortuna es una característica que está disponible en fetch y solo basta con agregar una línea para
indicarle si queremos que incluya cookies en la petición, literalmente:
fetch('https://jsonplaceholder.typicode.com/todos', {
credentials: 'include'
})
.then(console.log);
Credenciales en Fetch
include: Envía la cookie a cualquier origen de datos, es decir aquí no importa en qué dominio se
ejecuta esta acción.
same-origin: Envía la petición solo si el host solicitado coincide con el origen desde donde se esta
ejecutando el script.
CORS viene a ser una característica que resuelve en muchos casos el problema de realizar
solicitudes a dominios desconocidos, vulnerabilidades que normalmente son aprovechados por
piratas informáticos. A través de la opción mode puedes modificar el comportamiento:
fetch('https://jsonplaceholder.typicode.com/todos', {
mode: 'cors'
})
.then(response => response.json())
.then(console.log);
La configuración que definas aquí puede resultar crítico cuando solicitas recursos de otros
dominios, por eso ten en cuenta las siguientes opciones:
no-cors: Permite realizar solicitudes hacia cualquier origen sin embargo la respuesta se oculta para
impedir visualizar lo que viene como información.
same-origin: Permite realizar las solicitudes hacia el mismo dominio, caso contrario recibes más
que seguro un error.
Te cuento algo, muy aparte de poder utilizar esas opciones, tienes la facilidad de poder pasarle a
fetch tu propio objeto de Request, de la siguiente forma:
const myConfig = {
headers: {
'Content-Type': 'application/json'
'https://jsonplaceholder.typicode.com/todos',
myConfig
);
fetch(request)
.then(console.log)
A eso es que no referíamos con la flexibilidad, considéralo cuando necesites realizar algo similar
en tus proyectos web.
Respuesta
fetch("https://jsonplaceholder.typicode.com/todos")
Ejemplo básico
type: "cors"
url: "https://jsonplaceholder.typicode.com/todos"
redirected: false
status: 200
ok: true
statusText: ""
headers: Headers {}
body: (...)
bodyUsed: false
status: Código de estado HTTP.
ok: Devuelve un booleano con un true/false para indicar si la respuesta fue exitosa o no.
headers: Cabeceras devueltas.
Como lo mencionamos anteriormente, obtenemos una respuesta de una instancia del tipo
Response, por lo que tenemos acceso a ciertos métodos que nos resuelven la información de
acuerdo al tipo de dato que vamos a obtener.
fetch("https://jsonplaceholder.typicode.com/todos/1")
Ejemplo básico
Se apreciar muy bien que ejecutamos la función .json(), que obviamente indica que la data que
queremos ver es de tipo JSON, y devuelve una promesa que debe completarse hasta que termine
de formatear la información llegada del backend, el resultado debe ser similar a lo siguiente:
Respuesta de ejemplo
Pero esa no es la única función que tenemos disponible, existen otras más que debes conocer y
que te ahorrarán muchos dolores de cabeza en el futuro:
Esta función debe permitir dos cosas, primero, recibir una función que será ejecutada cafa vez que
se recibe trozos de información y segundo, nos permita manipular el objeto Response.
function progressReader(onProgress) { // 1
let loaded = 0;
start(controller) {
read(); // 5
function read() {
return reader
.read() // 6
loaded += value.byteLength;
controller.enqueue(value);
return read(); // 9
})
.catch(error => {
console.error(error);
controller.error(error);
});
});
};
Primero revisamos los pasos que tienen que ver con la forma que construimos la función.
1. Declaramos una función que espera un callback que servirá para notificar cada vez que reciba un
trozo de información.
2. Devuelve un closure que se usará para al momento que se resuelve la promesa, esta recibirá el
objeto Response.
La siguiente parte ya va un poco más a lo duro del ejercicio, jugar con Streams, vamos a intentar
hacerlo simple y entendible, para eso considera que el constructor del objeto ReadableStream,
espera que le pases un objeto con ciertas opciones, en este caso, usaremos clave start para
configurar cómo queremos que se comporte el lector de streams.
5. Ejecutamos por primera vez la función personalizada que empezará a leer los trozos de datos.
7. Si la información se ha terminado de leer, entonces "cierra el caño", es decir, indicar que la
transmisión concluyó.
Con eso ya estamos listos para implementarlo en nuestras solicitudes con fetch, sigamos con la
siguiente parte:
.then(streamProcessor) // 12
.then(blobData => {
// Blob data
});
Después de eso ya tienes disponible el recurso para insertarlo en cualquier parte de tu frontend.
Response
function GetAllRadioButtons() {
var arrInput = document.getElementsByTagName("input"), arrRadio = new Array();
var j = 0;
for (var i = 0; i < arrInput.length; i++) {
if (arrInput[i].type == "radio") {
arrRadio[j] = arrInput[i];
j++;
}
}
return arrRadio;
}
function GetAllSelectRadioButtons() {
var arrInput = document.getElementsByTagName("input"), arrRadio = [];
var j = 0;
for (var i = 0; i < arrInput.length; i++) {
if (arrInput[i].type == "radio" && arrInput[i].checked) {
arrRadio[j] = arrInput[i];
j++;
}
}
return arrRadio;
}
function getInputs() {
var matches = [];
[...form.elements].forEach((item) => {
console.log(item);
});