[ Conteúdo]: [ JavaScript ] [ Fetch ] Indo além ( Parte 1 )
Introdução
Nesta artigo vou falar sobre fetch
que é uma das coisas mais importantes de todo o JavaScript. Este artigo vai ter várias outras partes para entrar em questão assunto mais específico relacionado ao Fetch
como CORS
, Response Object
, Resquest Object
, Headers
, dentre outros assuntos. O foco deste é em: Conceitos básicos e úteis sobre Fetch Sem mais delongas:
O que é?
Fetch API é prove uma interface mais acessível a mais amigável para manipular partes de protocolos. Tal como requests
e responses
Fetch também prover um método global para buscar recursos assincronamente por toda a internet.
Fetch veio para substituir XMLHttpRequest
(que é uma forma mais antiga de buscar dados) tornando-se uma melhor alternativa nos tempos atuais por sua em pouco tempo por sua facilidade em service workers
Fetch também tem diversos conceitos mais avançados sobre HTTP como CORS
e outras extensões para HTTP.
Sintaxe
A sintaxe de Fetch é muito simples e amigável, segue o exemplo:
async function logMovies() {
const response = await fetch("http://example.com/movies.json");
const movies = await response.json();
console.log(movies);
}
Fetch pode ser usado em conjunto com funções assíncronas, alias, é muito comum isso acontecer.
Note que a sintaxe é bem simples, criamos um fetch
com o endereço do endpoint que queremos buscar os dados, quando buscar esses dados com sucesso (resolve
), vai entrar no modo response
. Note também que convertemos o resultado em JSON para conseguirmos manipula-lo como um objeto no nosso código, e tudo isso é feito assincronamente!
Fetch requests são controladas por
connect-src
diretiva deContent Security POlicy
Para mais detalhes pesquise mais a fundo por si mesmo
Objeto init e todos os paramêtros que são aceitos
Fetch pode receber um segundo argumento opcional que é chamado de init object
. Ele carrega várias informações junto com o request
feito pelo o fetch. Segue a lista:
// Example POST method implementation:
async function postData(url = "", data = {}) {
// Default options are marked with *
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
});
Fetch é bastante flexivél e fácil de utilizar, não acham? Não se preocupe com todos esses paramêtros, irei passar a pincelada nos mais importantes e alguns como headers
teria um artigo somente para ele.
Abortando um Fetch
É possível abordar uma soliticação Fetch caso ela não seja mais necessária ou simplesmente queria cancelar tudo, segue o exemplo.
const controller = new AbortController();
const signal = controller.signal;
const url = "video.mp4";
const downloadBtn = document.querySelector("#download");
const abortBtn = document.querySelector("#abort");
downloadBtn.addEventListener("click", async () => {
try {
const response = await fetch(url, { signal });
console.log("Download complete", response);
} catch (error) {
console.error(`Download error: ${error.message}`);
}
});
abortBtn.addEventListener("click", () => {
controller.abort();
console.log("Download aborted");
});
Utilizando o construtor new AbortController()
e seus métodos como signal
e abort()
, é possível interromper um request em fetch das mais variadas formas. Não entrarei muito a fundo sobre o construtor new AbortController()
pois é um tanto extenso e não é o foco.
Enviando um request com crendenciais
É possível enviar credenciais utilizando o paramêtro credentials
no objeto init
. Segue alguns dos valores possíveis:
include
: Vai enviar as credenciais para o servidor ou para qualquer outro lugar específicado. As credenciais enviadas: Cookies, HTTP authentication, e client-side SSL certificatessame-origem
: Envias as credenciais apenas para a URL que é de mesma origem do requestomit
: Não vai incluir as credenciais.
Exemplo incluíndo credenciais:
fetch("https://example.com", {
credentials: "include",
});
outros exemplos:
fetch("https://example.com", {
credentials: "same-origin",
});
fetch("https://example.com", {
credentials: "omit",
});
Ok, mas para que isso serve? Existem inúmeros exemplos! Podemos enviar as credenciais para verificar se o usuário está logado, ou é um usuário premium, dentre outras coisas. mas cuidado! informações dos usuários devem ser guardas a 7 chaves! Mantenha as devidas seguranças
Enviando arquivo JSON
Obviamente é possível enviar arquivos JSON e se comunicar com o Back-end assim. Segue o exemplo:
async function postJSON(data) {
const response = await fetch("https://example.com/profile", {
method: "POST", // or 'PUT'
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data),
});
}
Observe que é preciso específicar o tipo de conteúdo no Headers e fazer a conversão no body
. Além disso, não está presente no código, mas façam tratamento de erros com try
e catch
para evitar problemas!
Enviando um arquivo do inputFile
Fetch nos permite enviar arquivos que provem do <input type="file">
e isso é muito útil. Segue um exemplo básico:
importe o elemento
const input = document.getElementById('fileinput');
Crie um FormDate objeto:
const data = new FormData();
data.append('file', input.files[0]);
use Fetch para enviar os arquivos:
fetch('/upload-endpoint', {
method: 'POST',
body: data
})
E por fim, lide com erros:
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error))
Enviando múltiplos arquivos
Também é possível fazer o mesmo processo acima, só que com vários arquivos! Lembrese que o input tem que ter o atributo multiple
desta forma: <input type="file" multiple>
async function uploadMultiple(formData) {
try {
const response = await fetch("https://example.com/posts", {
method: "POST",
body: formData,
});
const result = await response.json();
console.log("Success:", result);
} catch (error) {
console.error("Error:", error);
}
}
const photos = document.querySelector('input[type="file"][multiple]');
const formData = new FormData();
formData.append("title", "My Vegas Vacation");
for (const [i, photo] of Array.from(photos.files).entries()) {
formData.append(`photos_${i}`, photo);
}
uploadMultiple(formData);
Checando se o Fetch foi um sucesso:
O fetche disponibiliza um método ok
para verificar se tudo ocorreu de maneira correta. Lembrando que erro 404 não é um erro de internet, portanto não vai ocorrer um aviso de erro no try
e catch
já que não é um erro de internet.
O método vai checkar a resolved
e retornar um booleano.
async function fetchImage() {
try {
const response = await fetch("flowers.jpg");
if (!response.ok) {
throw new Error("Network response was not OK");
}
const myBlob = await response.blob();
myImage.src = URL.createObjectURL(myBlob);
} catch (error) {
console.error("There has been a problem with your fetch operation:", error);
}
}
Criando seu próprio Request Object
Além de tudo que foi citado acima, também é possível criar um Request object que é semelhante a um Fetch.
async function fetchImage(request) {
try {
const response = await fetch(request);
if (!response.ok) {
throw new Error("Network response was not OK");
}
const myBlob = await response.blob();
myImage.src = URL.createObjectURL(myBlob);
} catch (error) {
console.error("Error:", error);
}
}
const myHeaders = new Headers();
const myRequest = new Request("flowers.jpg", {
method: "GET",
headers: myHeaders,
mode: "cors",
cache: "default",
});
fetchImage(myRequest);
Conclusão
Iae, gostaram? Ainda vai ter as outras partes explicando mais detalhadamente sobre o fetch e suas funcionalidades. Cometi algum erro? Me corrijam!