Solucionado (ver solução)
Solucionado
(ver solução)
8
respostas

Dificuldade para realizar fetch

Estou tentando integrar a api que eu realizei em Java com spring, porém, estou encontrando dificuldades para realizar o fetch() em javascript; Ao tentar o seguinte código:

console.log(fetch('http://localhost:8080/todos'))

Retorna o seguinte erro: http://prntscr.com/rp2wkc

Ao adicionar oque é pedido:

console.log(fetch('http://localhost:8080/todos',{mode: 'no-cors'}));  

Ele até devolve a promise, porém da seguinte maneira: http://prntscr.com/rp2xu5

A requisição pelo arquivo cliente.html gera um log no servidor igual ao do postman, porém, a promise vem com ok:false.

(Observação: o /todos é o endpoint que eu setei, fazendo os testes pelo postman funciona perfeitamente.)

Ja utilizei o @CrossOrigin, porém não funcionou.

Alguém sabe como tratar isso?

8 respostas

Olá Maria, tudo bem com você?

Eu ainda não entendo muito de spring, mas vou responder com base nos conhecimentos de javascript, pois acredito que ai que está acontecendo o problema

Quando utilizamos o fetch estamos criando uma promise que leva um tempo para obter o seu resultado, por isso quando você da console.log(fetch ele esta devolvendo uma Promise<Peding>, ou seja, pedimos para printar no console antes de terminar de executar o nosso fetch

Para corrigir isso precisamos utilizar o then que só é executado após terminar a execução da promise, então acredito que o que você quer seria obtido da seguinte maneira:

fetch('http://localhost:8080/todos', { mode: 'no-cors'})
    .then( data => data.json())
    .then(console.log)
    .catch( error => console.log(error));

O que eu estou fazendo é o seguinte, eu peço para ele fazer a requisição no nosso endpoint, e após terminar é para ele pegar o resultado ( que eu estou chamando de data ) e transformar em um json (para poder ter acesso aos dados retornados pelo nosso servidor) e após isso ele vai para o segundo then que irá printar na tela o resultado obtido.

Aqui poderíamos pegar o dados e salvar em um array, ou passar para uma função, por exemplo:

fetch('http://localhost:8080/todos', { mode: 'no-cors'})
    .then( data => data.json())
    .then( dados => meuArray.push(dados))
    .catch( error => console.log(error));

Ou seja transformamos o data em um json e isso retorna uma nova promise, iremos pegar o resultado (em formato json) dentro do atributo dados e estou passando uma função para adicionar os dados dentro de um array :)

Caso de erro ele irá para o catch apenas para devolver o erro que aconteceu!

Aqui na alura temos um curso apenas em relação afetch api para entender todas as particularidades dessa ferramenta: Fetch API: Consumindo uma API Rest com Javascript

Você pode testar?

Abraços e Bons Estudos!

Oi Maria,

Como a aplicação no frontend está em um endereço diferente da aplicação backend(API) e as requisições estão sendo feitas via JavaScript, o browser vai bloquear por conta de na API não estar configurado o CORS, permitindo requisições JS cross-domain.

Você precisa criar na API a seguinte classe:

@Configuration
public class CorsConfiguration implements WebMvcConfigurer {

    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
            .allowedOrigins("http://localhost:3000")
            .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD", "TRACE", "CONNECT");
    }
}

Lembrando de substituir o localhost:3000 para o endereço do seu frontend.

Desse jeito a API vai permitir ao browser que dispare requisições JS normalmente.

Veja se resolve no seu caso.

Bons estudos!

Olá,

Criei a classe com o localhost:8080 certinho e também tentei utilizar o código passado

fetch('http://localhost:8080/todos', { mode: 'no-cors'})
    .then( data => data.json())
    .then( dados => meuArray.push(dados))
    .catch( error => console.log(error));

Porém não obtive sucesso ele retorna o seguinte erro: https://prnt.sc/rpk7jo

Minha api esta disponibilizada no git(https://github.com/DudaMoraes/desafioapi), porém, nao se encontra com a classe CorsConfiguration ja que atualizei muito recentemente e ainda nao subi o codigo atualizado para lá.

Consegue postar aqui o código da sua classe de configuração do CORS?

package br.com.desafio.springbootapi.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class CorsConfiguration implements WebMvcConfigurer {

    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
            .allowedOrigins("http://localhost:8080")
            .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD", "TRACE", "CONNECT");
    }
}
solução!

Então Maria Eduarda,

Eu fiz download do seu projeto e consegui obter os todos normalmente adicionando apenas a anotação de @CrossOrigin nas rotas do tipo GET e fazendo o fetch normalmente, vou te mandar as imagens para você ver: API Spring + Fetch

Se você puder mandar o seu código javascript para a gente analisar, acredito que deve ter algum errinho :)

Abraços e Bons Estudos!

Oi Maria,

Analisando sua classe CorsConfiguration, vi que o endreço que você está liberando é o localhost:8080, que acredito ser o endereço da própria API, mas na verdade você deve passar o endereço da aplicação front-end.

Veja se não é esse o problema.

Acredito que era um problema no próprio javascript, reescrevi meu código baseado no seu e consegui resgatar os dados pela api.

Agora a promise esta gerando ok:true.

Muito obrigada pela ajuda!

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software