5
respostas

No 'Access-Control-Allow-Origin' header is present on the requested resource.

Eu estou fazendo o Challenge 5 Edição da Alura e fiz uma fake REST API para guardar os dados dos produtos. Porém, depois que eu dei Deploy na API (pelo cyclic), para o site funcionar fora da minha máquina começou a dar erro de "No 'Access-Control-Allow-Origin' header is present on the requested resource".

Eu já procurei maneiras de resolver o erro, mas não consegui e ainda não entendo muito de backend.

Observação: O site estava funcionando normalmente com todos os métodos de requisições. Só parou de funcionar depois que adicionei o método 'PUT'.

Aqui está o código do backend que usei

const jsonServer = require('json-server')
const cors = require('cors')
const path = require('path')

const server = jsonServer.create()
const router = jsonServer.router(path.join(__dirname, 'db.json'))
const middlewares = jsonServer.defaults()

server.use(cors())
server.use(jsonServer.bodyParser)
server.use(middlewares)
server.use(router)

const PORT = 8000

server.listen(PORT, () => {
  console.log(`JSON Server is running on http://localhost:${PORT}`)
})

Código do fetch e da edição(PUT) :

async function listaProdutos() {
    const resposta = await fetch(`https://zany-cyan-coral-veil.cyclic.app/produtos`)
    const respostaConvertida = await resposta.json();
    
    return respostaConvertida;
}

async function criaProduto(categoria, descricao, nome, preco, url) {
    const resposta = await fetch(`https://zany-cyan-coral-veil.cyclic.app/produtos`, {
        method: 'POST',
        headers: {
            'Content-type' : 'application/json'
        },
        body: JSON.stringify({
            categoria: categoria,
            descricao: descricao,
            nome: nome,
            preco: preco,
            url: url
        })
    })
    const respostaConvertida = await resposta.json();

    return respostaConvertida;
}

async function deletaProduto(id) {
    const resposta = await fetch(`https://zany-cyan-coral-veil.cyclic.app/produtos/${id}`, {
        method: 'DELETE'
    })
    const respostaConvertida = resposta.json();

    return respostaConvertida;
}

async function buscaProduto(termoDeBusca) {
    const resposta = await fetch(`https://zany-cyan-coral-veil.cyclic.app/produtos?q=${termoDeBusca}`)
    const respostaConvertida = resposta.json();

    return respostaConvertida;
}

async function detalhaProduto(id) {
    const resposta = await fetch(`https://zany-cyan-coral-veil.cyclic.app/produtos/${id}`)
    const respostaConvertida = resposta.json();

    return respostaConvertida;
}

async function atualizaProduto(id, url, categoria, nome, preco, descricao) {
    const resposta = await fetch(`https://zany-cyan-coral-veil.cyclic.app/produtos/${id}`, {
        method: 'PUT',
        headers: {
            'Content-type' : 'application/json'
        },
        body: JSON.stringify({
            url: url,
            categoria: categoria,
            nome: nome,
            preco: preco,
            descricao: descricao
        })
    })
    const respostaConvertida = await resposta.json();

    return respostaConvertida;
}

export const produtoService = {
    listaProdutos,
    criaProduto,
    deletaProduto,
    buscaProduto,
    detalhaProduto,
    atualizaProduto
};
import { produtoService } from "./fetch.js";

const pegaURL = new URL(window.location);
const id = pegaURL.searchParams.get('id');

const inputURL = document.querySelector("[data-url]");
const inputCategoria = document.querySelector("[data-categoria]");
const inputNome = document.querySelector("[data-nome]");
const inputPreco = document.querySelector("[data-preco]");
const inputDescricao = document.querySelector("[data-descricao]");

produtoService.detalhaProduto(id)
.then(dados => {
    inputURL.value = dados.url;
    inputCategoria.value = dados.categoria;
    inputNome.value = dados.nome;
    inputPreco.value = dados.preco;
    inputDescricao.value = dados.descricao;
});

const formulario = document.querySelector("[data-formulario]");

formulario.addEventListener("submit", evento => {
    evento.preventDefault();
    produtoService.atualizaProduto(id, inputURL.value, inputCategoria.value, inputNome.value, inputPreco.value, inputDescricao.value)
    .then(()=> {
        window.location.href = "./editado.html"
    })
})
5 respostas

Segue também a imagem do erro que aparece no console:

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Olá, Alex!

Esse erro "No 'Access-Control-Allow-Origin' header is present on the requested resource" ocorre quando você está fazendo uma requisição de um domínio diferente ao qual a API está hospedada. Isso é uma medida de segurança implementada pelos navegadores para evitar que scripts maliciosos acessem recursos de outros domínios sem permissão.

Para resolver esse problema, você precisa adicionar o cabeçalho 'Access-Control-Allow-Origin' na sua API, permitindo que o seu site possa fazer requisições a partir de um domínio diferente. No seu código do backend, você pode adicionar o seguinte código logo abaixo da linha server.use(cors()):

server.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*');
  next();
});

Dessa forma, você estará permitindo que qualquer domínio possa fazer requisições para a sua API. Se você quiser restringir o acesso apenas a um domínio específico, você pode substituir o '*' pelo domínio desejado.

Espero que isso resolva o seu problema! Se tiver mais alguma dúvida, é só perguntar. Bons estudos!

Oi, Emerson, tudo bem?

Eu acrescentei o código que você sugeriu mas o erro persiste.

Quando eu faço a requisição de 'PUT', por exemplo, para editar algum item no site, o erro aparece no console e o programa não vai para a página html que eu indiquei no código.

Mas se eu for até a página onde os itens estão, ele estará editado. Mesmo com as mensagens de erro.

Uma tentativa é explicitar os métodos que estará permitindo, seguindo o código abaixo:

const corsOpts = {
  origin: '*',

  methods: [
    'GET',
    'POST',
    'PUT'
  ],

  allowedHeaders: [
    'Content-Type'
  ]
}

server.use(cors(corsOpts))

Para te auxiliar, separei esses 2 conteúdos sobre o assunto:

Caso o erro persista, me manda o código completo via github por favor :)

Coloquei o trecho de código mas o erro ainda persiste :(

O código da fake API está nesse repositório: https://github.com/alexxgoomes/json-server-alurageek

E o Front-End está nesse: https://github.com/alexxgoomes/AluraGeek

Muito obrigado pelo apoio, Emerson :)