Fetch API es una API de JavaScript basada en promesas para realizar solicitudes HTTP asíncronas en el navegador de forma similar a XMLHttpRequest (XHR). A diferencia de XHR, es una API simple y limpia que utiliza promesas para proporcionar un conjunto de funciones más potente y flexible para obtener recursos del servidor.
Fetch API está bastante estandarizado ahora y es compatible con todos los navegadores modernos, excepto IE. Si necesita admitir todos los navegadores, incluido IE, solo agregue un polyfill lanzado por GitHub a su proyecto.
Uso básico de la API
Usar Fetch API es realmente simple. Simplemente pase la URL, la ruta al recurso que desea obtener, a fetch()
método:
fetch('/js/users.json')
.then(response => {
// handle response data
})
.catch(err => {
// handle errors
});
Pasamos la ruta del recurso que queremos recuperar como parámetro a fetch()
. Devuelve una promesa que pasa la respuesta a then()
cuando se cumple. El catch()
El método intercepta errores si la solicitud no se completa debido a una falla en la red o por cualquier otra razón.
Solicitud OBTENER
De manera predeterminada, Fetch API usa el método GET para solicitudes asíncronas. Usemos la API REST de Reqres para recuperar una lista de usuarios que usan la solicitud GET:
fetch('https://reqres.in/api/users')
.then(res => res.json())
.then(res => {
res.data.map(user => {
console.log(`${user.id}: ${user.first_name} ${user.last_name}`);
});
});
La solicitud anterior imprime lo siguiente en la consola:
1: George Bluth
2: Janet Weaver
3: Emma Wong
Llamando a fetch()
método devuelve una promesa. La respuesta devuelta por la promesa es un objeto de flujo, lo que significa que cuando llamamos a json()
método, devuelve otra promesa. Llamar al json()
El método indica que estamos esperando una respuesta JSON. Si espera una respuesta XML, debe usar text()
método.
Solicitud POST
Al igual que Axios, Fetch también nos permite usar cualquier otro método HTTP en la solicitud:POST, PUT, DELETE, HEAD y OPTIONS. Todo lo que necesita hacer es establecer el method
y body
parámetros en el fetch()
opciones:
const user = {
first_name: 'John',
last_name: 'Lilly',
job_title: 'Software Engineer'
};
const options = {
method: 'POST',
body: JSON.stringify(user),
headers: {
'Content-Type': 'application/json'
}
}
fetch('https://reqres.in/api/users', options)
.then(res => res.json())
.then(res => console.log(res));
La API de Reqres nos devuelve los datos del cuerpo con un ID y una marca de tiempo creada adjunta:
{
"first_name":"John",
"last_name":"Lilly",
"job_title":"Software Engineer",
"id":"482",
"createdAt":"2019-05-12T15:09:13.140Z"
}
Solicitud de ELIMINACIÓN
La solicitud DELETE se parece mucho a la solicitud POST excepto body
no es obligatorio:
const options = {
method: 'DELETE',
headers: {
'Content-Type': 'application/json'
}
}
fetch('https://reqres.in/api/users/2', options)
.then(res => {
if (res.ok) {
return Promise.resolve('User deleted.');
} else {
return Promise.reject('An error occurred.');
}
})
.then(res => console.log(res));
Gestión de errores
Desde el fetch()
método devuelve una promesa, el manejo de errores es fácil. Podemos usar el catch()
método de la promesa de interceptar cualquier error que se produzca durante la ejecución de la solicitud. Sin embargo, no se generará ningún error si la solicitud llega al servidor y regresa, independientemente de la respuesta que haya devuelto el servidor. La promesa devuelta por el fetch()
no rechaza los errores HTTP incluso si el código de respuesta HTTP es 404 o 500.
Afortunadamente, puedes usar el ok
propiedad del objeto de respuesta para verificar si la solicitud fue exitosa o no:
fetch('https://reqres.in/api/users/22') // 404 Error
.then(res => {
if (res.ok) {
return res.json();
} else {
return Promise.reject(res.status);
}
})
.then(res => console.log(res))
.catch(err => console.log(`Error with message: ${err}`));
Encabezados de solicitud
Encabezados de solicitud (como Accept
, Content-Type
, User-Agent
, Referer
, etc.) son una parte esencial de cualquier solicitud HTTP. Headers
de la API Fetch El objeto nos permite establecer, eliminar o recuperar encabezados de solicitud HTTP.
Podemos crear un objeto de encabezado usando el Headers()
constructor y luego use el append
, has
, get
, set
y delete
métodos para modificar encabezados de solicitud:
// create an empty `Headers` object
const headers = new Headers();
// add headers
headers.append('Content-Type', 'text/plain');
headers.append('Accept', 'application/json');
// add custom headers
headers.append('X-AT-Platform', 'Desktop');
headers.append('X-AT-Source', 'Google Search');
// check if header exists
headers.has('Accept'); // true
// get headers
headers.get('Accept'); // application/json
headers.get('X-AT-Source'); // Google Search
// update header value
headers.set('Content-Type', 'application/json');
// remove headers
headers.delete('Content-Type');
headers.delete('X-AT-Platform');
También podemos pasar una matriz de matrices o un objeto literal al constructor para crear un objeto de encabezado:
// passing an object literal
const headers = new Headers({
'Content-Type': 'application/json',
'Accept': 'application/json'
});
// OR
// passing an array of arrays
const headers = new Headers([
['Content-Type', 'application/json'],
['Accept', 'application/json']
]);
Para agregar encabezados a la solicitud, simplemente cree un Request
instancia, y pásela a fetch()
método en lugar de la URL:
const request = new Request('https://reqres.in/api/users', {
headers: headers
});
fetch(request)
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error('Error:', err));
Objeto de solicitud
El Request
El objeto representa una solicitud de recursos y se puede crear llamando al Request()
constructor:
const request = new Request('https://reqres.in/api/users');
El Request
object también acepta un objeto URL:
const url = new URL('https://reqres.in/api/users');
const request = new Request(url);
Pasando un Request
objetar a fetch()
, puede personalizar fácilmente las propiedades de la solicitud:
method
— Método HTTP comoGET
,POST
,PUT
,DELETE
,HEAD
url
— La URL de la solicitud, una cadena o un objeto de URLheaders
— unHeaders
objeto para encabezados de solicitudreferrer
— remitente de la solicitud (p. ej.,client
)mode
— El modo para solicitudes de origen cruzado (p. ej.,cors
,no-cors
,same-origin
)credentials
— ¿Deberían acompañar la solicitud las cookies y los encabezados de autorización HTTP? (por ejemplo,include
,omit
,same-origin
)redirect
— El modo de redirección de la solicitud (por ejemplo,follow
,error
,manual
)integrity
— El valor de integridad del subrecurso de la solicitudcache
— El modo de caché de la solicitud (por ejemplo,default
,reload
,no-cache
)
Vamos a crear un Request
objeto con algunas propiedades personalizadas y contenido del cuerpo para realizar una solicitud POST:
const user = {
first_name: 'John',
last_name: 'Lilly',
job_title: 'Software Engineer'
};
const headers = new Headers({
'Content-Type': 'application/json',
'Accept': 'application/json'
});
const request = new Request('https://reqres.in/api/users', {
method: 'POST',
headers: headers,
redirect: 'follow',
mode: 'cors',
body: JSON.stringify(user)
});
fetch(request)
.then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error('Error:', err));
Solo se requiere el primer argumento, la URL. Todas estas propiedades son de solo lectura, lo que significa que no puede cambiar su valor una vez que se crea el objeto de solicitud. La API Fetch no requiere estrictamente un Request
objeto. El objeto literal, lo pasamos a fetch()
método, actúa como un Request
objeto:
fetch('https://reqres.in/api/users', {
method: 'POST',
headers: headers,
redirect: 'follow',
mode: 'cors',
body: JSON.stringify(user)
}).then(res => res.json())
.then(json => console.log(json))
.catch(err => console.error('Error:', err));
Objeto de respuesta
El Response
objeto devuelto por el fetch()
contiene la información sobre la solicitud y la respuesta de la solicitud de red, incluidos los encabezados, el código de estado y el mensaje de estado:
fetch('https://reqres.in/api/users')
.then(res => {
// get response headers
console.log(res.headers.get('content-type'));
console.log(res.headers.get('expires'));
// HTTP response status code
console.log(res.status);
// shorthand for `status` between 200 and 299
console.log(res.ok);
// status message of the response e.g. `OK`
console.log(res.statusText);
// check if there was a redirect
console.log(res.redirected);
// get the response type (e.g., `basic`, `cors`)
console.log(res.type);
// the full path of the resource
console.log(res.url);
});
Se puede acceder al cuerpo de la respuesta a través de los siguientes métodos:
json()
devuelve el cuerpo como un objeto JSONtext()
devuelve el cuerpo como una cadenablob()
devuelve el cuerpo como un objeto BlobformData()
devuelve el cuerpo como un objeto FormDataarrayBuffer()
devuelve el cuerpo como un objeto ArrayBuffer
Todos estos métodos devuelven una promesa. Aquí hay un ejemplo de text()
método:
fetch('https://reqres.in/api/unknown/2')
.then(res => res.text())
.then(res => console.log(res));
El resultado de la llamada de red anterior será una cadena JSON:
'{"data":{"id":2,"name":"fuchsia rose","year":2001,"color":"#C74375","pantone_value":"17-2031"}}'
Obtener y cookies
De forma predeterminada, cuando utiliza Fetch para obtener un recurso, la solicitud no contiene credenciales como cookies. Si desea enviar cookies, debe habilitar explícitamente las credenciales como se muestra a continuación:
fetch(url, {
credentials: 'include'
})
Obtener y Asíncrono/Esperar
Dado que Fetch es una API basada en promesas, podemos ir un paso más allá y usar la última sintaxis async/await de ES2017 para hacer que nuestro código sea aún más simple y sincrónico:
const fetchUsers = async () => {
try {
const res = await fetch('https://reqres.in/api/users');
if (!res.ok) {
throw new Error(res.status);
}
const data = await res.json();
console.log(data);
} catch (error) {
console.log(error);
}
}
fetchUsers();
Conclusión
Eso es todo para la introducción a JavaScript Fetch API. Es una gran mejora con respecto a XMLHttpRequest
con una interfaz simple, elegante y fácil de usar. Fetch funciona muy bien para obtener recursos de red (incluso a través de la red dentro de los trabajadores del servicio). La API Fetch es compatible con todos los navegadores modernos, por lo que no hay necesidad de usar ningún relleno a menos que desee admitir IE.