[ Web Proxy ]
URL:
Viewing: https://developer.mozilla.org/es/docs/Web/API/Fetch_API/Using_Fetch [Back]  [Original]

Uso de Fetch - API web | MDN

Esta pgina ha sido traducida del ingls por la comunidad. Aprende ms y nete a la comunidad de MDN Web Docs.

View in English Always switch to English

Uso de Fetch

Experimental: Esta es una tecnologa experimental
Comprueba la Tabla de compabilidad de navegadores cuidadosamente antes de usarla en produccin.

La API Fetch proporciona una interfaz JavaScript para acceder y manipular partes del canal HTTP, tales como peticiones y respuestas. Tambin provee un mtodo global fetch() que proporciona una forma fcil y lgica de obtener recursos de forma asncrona por la red.

Este tipo de funcionalidad se consegua previamente haciendo uso de XMLHttpRequest. Fetch proporciona una alternativa mejor que puede ser empleada fcilmente por otras tecnologas como Service Workers. Fetch tambin aporta un nico lugar lgico en el que definir otros conceptos relacionados con HTTP como CORS y extensiones para HTTP.

La especificacin fetch difiere de JQuery.ajax() en dos formas principales:

  • El objeto Promise devuelto desde fetch() no ser rechazado con un estado de error HTTP incluso si la respuesta es un error HTTP 404 o 500. En cambio, este se resolver normalmente (con un estado ok configurado a false), y este solo sera rechazado ante un fallo de red o si algo impidi completar la solicitud.
  • Por defecto, fetch no enviar ni recibir cookies del servidor, resultando en peticiones no autenticadas si el sitio permite mantentener una sesin de usuario (para mandar cookies, credentials de la opcin init deberan ser configuradas). Desde el 25 de agosto de 2017. La especificacin cambi la politica por defecto de las credenciales a same-origin. Firefox cambi desde la versin 61.0b13.

Una peticin bsica de fetch es realmente simple de realizar. Eche un vistazo al siguente cdigo:

fetch('http://example.com/movies.json')
  .then(response => response.json())
  .then(data => console.log(data));

Aqu estamos recuperando un archivo JSON a travs de red e imprimiendo en la consola. El uso de fetch() ms simple toma un argumento (la ruta del recurso que quieres obtener) y devuelve un objeto Promise conteniendo la respuesta, un objeto Response.

Esto es, por supuesto, una respuesta HTTP no el archivo JSON. Para extraer el contenido en el cuerpo del JSON desde la respuesta, usamos el mtodo json() (definido en el mixin de Body, el cual est implementado por los objetos Request y Response).

Nota: El mixin de Body tambien tiene metodos parecidos para extraer otros tipos de contenido del cuerpo. Vease Body para ms informacin.

Las peticiones de Fetch son controladas por la directiva de connect-src de Content Security Policy en vez de la directiva de los recursos que se han devuelto.

In this article

Suministrando opciones de peticin

El mtodo fetch() puede aceptar opcionalmente un segundo parmetro, un objeto init que permite controlar un numero de diferentes ajustes:

Vea fetch(), para ver todas las opciones disponibles y ms detalles.

// Ejemplo implementando el metodo POST:
async function postData(url = '', data = {}) {
  // Opciones por defecto estan marcadas con un *
  const response = await fetch(url, {
    method: 'POST', // *GET, POST, PUT, DELETE, etc.
    mode: 'cors', // no-cors, *cors, same-origin
    cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
    credentials: 'same-origin', // include, *same-origin, omit
    headers: {
      'Content-Type': 'application/json'
      // 'Content-Type': 'application/x-www-form-urlencoded',
    },
    redirect: 'follow', // manual, *follow, error
    referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
    body: JSON.stringify(data) // body data type must match "Content-Type" header
  });
  return response.json(); // parses JSON response into native JavaScript objects
}

postData('https://example.com/answer', { answer: 42 })
  .then(data => {
    console.log(data); // JSON data parsed by `data.json()` call
  });

Tenga en cuenta que mode: "no-cors" solo permite un conjunto limitado de encabezados en la solicitud:

  • Accept
  • Accept-Language
  • Content-Language
  • Content-Type with a value of application/x-www-form-urlencoded, multipart/form-data, or text/plain

Comprobando que la peticin es satisfactoria

Una peticin promise fetch() ser rechazada con TypeError cuando se encuentre un error de red, aunque esto normalmente significa problemas de permisos o similares por ejemplo, un 404 no constituye un error de red. Una forma precisa de comprobar que la peticin fetch() es satisfactoria pasa por comprobar si la promesa ha sido resuelta, adems de comprobar que la propiedad Response.ok tiene el valor true que indica que el estado de la peticin HTTP es OK (cdigo 200-299). El cdigo sera algo as:

js
fetch("flores.jpg")
  .then(function (response) {
    if (response.ok) {
      response.blob().then(function (miBlob) {
        var objectURL = URL.createObjectURL(miBlob);
        miImagen.src = objectURL;
      });
    } else {
      console.log("Respuesta de red OK pero respuesta HTTP no OK");
    }
  })
  .catch(function (error) {
    console.log("Hubo un problema con la peticin Fetch:" + error.message);
  });

Proporcionando tu propio objeto Request

En lugar de pasar la ruta al recurso que deseas solicitar a la llamada del mtodo fetch(), puedes crear un objeto de peticin utilizando el constructor Request(), y pasarlo como un argumento del mtodo fetch():

js
var myHeaders = new Headers();

var myInit = {
  method: "GET",
  headers: myHeaders,
  mode: "cors",
  cache: "default",
};

var myRequest = new Request("flowers.jpg", myInit);

fetch(myRequest)
  .then(function (response) {
    return response.blob();
  })
  .then(function (myBlob) {
    var objectURL = URL.createObjectURL(myBlob);
    myImage.src = objectURL;
  });

Request() acepta exactamente los mismos parmetros que el mtodo fetch(). Puedes incluso pasar un objeto de peticin existente para crear una copia del mismo:

js
var anotherRequest = new Request(myRequest, myInit);

Esto es muy til ya que el cuerpo de las solicitudes y respuestas son de un slo uso. Haciendo una copia como esta te permite utilizar la peticin/respuesta de nuevo, y al mismo tiempo, si lo deseas, modificar las opciones de init. La copia debe estar hecha antes de la lectura del <body>, y leyendo el <body> en la copia, se marcar como leido en la peticin original.

Nota: Existe tambin un mtodo clone() que crea una copia. Este tiene una semntica ligeramente distinta al otro mtodo de copia el primero fallar si el cuerpo de la peticin anterior ya ha sido ledo (lo mismo para copiar una respuesta), mientras que clone() no.

Enviar una peticin con credenciales incluido

Para producir que los navegadores envien una peticin con las credenciales incluidas, incluso para una llamada de origen cruzado, aadimos credentials: 'include' en el el objeto init que se pasa al mtodo fetch().

js
fetch("https://example.com", {
  credentials: "include",
});

Si solo quieres enviar la credenciales si la URL de la peticin est en el mismo origen desde donde se llamada el script, aade credentials: 'same-origin'.

js
// El script fu llamado desde el origen 'https://example.com'

fetch("https://example.com", {
  credentials: "same-origin",
});

Sin embargo para asegurarte que el navegador no incluye las credenciales en la peticin, usa credentials: 'omit'.

js
fetch("https://example.com", {
  credentials: "omit",
});

Enviando datos JSON

Usa fetch() para enviar una peticin POST con datos codificados en JSON .

js
var url = "https://example.com/profile";
var data = { username: "example" };

fetch(url, {
  method: "POST", // or 'PUT'
  body: JSON.stringify(data), // data can be `string` or {object}!
  headers: {
    "Content-Type": "application/json",
  },
})
  .then((res) => res.json())
  .catch((error) => console.error("Error:", error))
  .then((response) => console.log("Success:", response));

Enviando un archivo

Los archivos pueden ser subido mediante el HTML de un elemento input <input type="file" />, FormData() y fetch().

js
var formData = new FormData();
var fileField = document.querySelector("input[type='file']");

formData.append("username", "abc123");
formData.append("avatar", fileField.files[0]);

fetch("https://example.com/profile/avatar", {
  method: "PUT",
  body: formData,
})
  .then((response) => response.json())
  .catch((error) => console.error("Error:", error))
  .then((response) => console.log("Success:", response));

Cabeceras

La interfaz Headers te permite crear tus propios objetos de headers mediante el constructor Headers(). Un objeto headers es un simple multi-mapa de nombres y valores:

js
var content = "Hello World";
var myHeaders = new Headers();
myHeaders.append("Content-Type", "text/plain");
myHeaders.append("Content-Length", content.length.toString());
myHeaders.append("X-Custom-Header", "ProcessThisImmediately");

Lo mismo se puede lograr pasando un "array de arrays" o un objeto literal al constructor:

js
myHeaders = new Headers({
  "Content-Type": "text/plain",
  "Content-Length": content.length.toString(),
  "X-Custom-Header": "ProcessThisImmediately",
});

Los contenidos pueden ser consultados o recuperados:

js
console.log(myHeaders.has("Content-Type")); // true
console.log(myHeaders.has("Set-Cookie")); // false
myHeaders.set("Content-Type", "text/html");
myHeaders.append("X-Custom-Header", "AnotherValue");

console.log(myHeaders.get("Content-Length")); // 11
console.log(myHeaders.getAll("X-Custom-Header")); // ["ProcessThisImmediately", "AnotherValue"]

myHeaders.delete("X-Custom-Header");
console.log(myHeaders.getAll("X-Custom-Header")); // [ ]

Algunas de estas operaciones solo sern utiles en ServiceWorkers, pero estas disponen de una mejor API para manipular headers.

Todos los mtodosde de headers lanzan un TypeError si un nombre de cabecera no es un nombre de cabecera HTTP vlido. Las operaciones de mutacin lanzarn un TypeError si hay un guarda inmutable (ver ms abajo). Si no, fallan silenciosamente. Por ejemplo:

js
var myResponse = Response.error();
try {
  myResponse.headers.set("Origin", "http://mybank.com");
} catch (e) {
  console.log("Cannot pretend to be a bank!");
}

Un buen caso de uso para headers es comprobar cuando el tipo de contenido es correcto antes de que se procese:

js
fetch(myRequest).then(function (response) {
  var contentType = response.headers.get("content-type");
  if (contentType && contentType.indexOf("application/json") !== -1) {
    return response.json().then(function (json) {
      // process your JSON further
    });
  } else {
    console.log("Oops, we haven't got JSON!");
  }
});

Guarda (Guard)

Desde que las cabeceras pueden ser enviadas en peticiones y recibidas en respuestas, y tienen limitaciones sobre que informacin puede y debera ser mutable, los objeto headers tienen una propierdad de guarda. Este no est expuesto a la Web, pero puede afectar a que operaciones de mutacin son permitidas sobre el objeto headers.

Los valores posibles de guarda (guard) son:

  • none: valor por defecto.
  • request: Guarda para el objeto headers obtenido de la peticin (Request.headers).
  • request-no-cors: Guarda para un objeto headers obtenido desde una peticin creada con Request.mode a no-cors.
  • response: Guarda para una cabecera obetenida desde un respuesta (Response.headers).
  • immutable: Mayormente utilizado para ServiceWorkers, produce un objeto headers de solo lectura.

Nota: No se debera aadir o establecer una peticin a un objeto headers guardado con la cabecera Content-Length. De igual manera, insertar Set-Cookie en la respuesta de la cabecera no esta permitido: ServiceWorkers no estan autorizados a establecer cookies a travs de respuestas sintticas.

Objetos Response

Cmo has visto anteriormente, las instancias de Response son devueltas cuando fetch() es resuelto.

Las propiedades de response que usars son:

  • Response.status Entero (por defecto con valor 200) que contiene el cdigo de estado de las respuesta.
  • Response.statusText Cadena (con valor por defecto "OK"), el cual corresponde al mensaje del estado de cdigo HTTP.
  • Response.ok Visto en uso anteriormente, es una clave para comprobar que el estado est dentro del rango 200-299 (ambos incluidos). Este devuelve un valor Boolean, siendo true si lo anterior se cumple y false en otro caso.

Estos pueden tambin creados programticamente a travs de JavaScript, pero esto solamente es realmete til en ServiceWorkers, cuando pones un objeto response personalizado a una respuesta recibida usando un mtodo respondWith():

js
var myBody = new Blob();

addEventListener("fetch", function (event) {
  event.respondWith(
    new Response(myBody, {
      headers: { "Content-Type": "text/plain" },
    }),
  );
});

El constructor Response() toma dos argurmentos opcionales, un cuerpo para la respuesta y un objeto init (similar al que acepta Request()).

Nota: El mtodo esttico error() simplemente devuelve un error en la respuesta. De igual manera que redirect() devuelve una respuesta que resulta en un redireccin a una URL especificada. Estos son solo relevantes tambien a ServiceWorkers.

Body

Tanto las peticiones como las respuestas pueden contener datos body. Body es una instancia de cualquiera de los siguientes tipos:

El mixin de Body define los siguientes metodos para extraer un body (implementado por Request and Response). Todas ellas devuelven una promesa que es eventualmente resuelta con el contenido actual.

Este hace uso de los datos no texttuales mucho mas facil que si fuera con XHR.

Las peticiones body pueden ser establecidas pasando el parametro body:

js
var form = new FormData(document.getElementById("login-form"));
fetch("/login", {
  method: "POST",
  body: form,
});

Tanto peticiones y respuestas (y por extensin la function fetch()), intentaran inteligentemente determinar el tipo de contenido. Una peticin tambien establecer automticamente la propiedad Context-Type de la cabecera si no es ha establecido una.

Detectar caracterstica

Puedes comprobar si el navegador soporta la API de Fetch comprobando la existencia de Headers, Request, Response o fetch() sobre el mbito de Window o Worker. Por ejemplo:

js
if (self.fetch) {
  // run my fetch request here
} else {
  // do something with XMLHttpRequest?
}

Polyfill

Para utilizar fetch() en un explorador no soportado, hay disponible un Fetch Polyfill que recrea la funcionalidad para navegadores no soportados.

Vea tambin


Web Proxy Viewer  |  New URL  |  Original Page