2
respostas

Erro "Access to XMLHttpRequest...blocked by CORS policy" ao passar a url "/negociacoes" para o método post

Olá Alura!

Está ocorrendo o erro abaixo, ao considerar a url "/negociacoes" no método post(url, dado) da classe HttpService:

"HttpService.js:44 Access to XMLHttpRequest at 'file:///negociacoes' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https."

Vocês poderiam me explicar o porquê e como resolver (sem alterar a url)? Obs: pesquisando descobri que o erro não ocorre ao passar a url completa ("http://localhost:3000/negociacoes"), porém gostaria de entender porque para o instrutor (e pelo jeito para os demais colegas também) não ocorre(u) este erro com a url "/negociacoes".

Código (é o mesmo da resposta do instrutor nesta atividade):

class HttpService {

    get(url) {

        // código omitido
    }

    post(url, dado) {


        return new Promise((resolve, reject) => {

            let xhr = new XMLHttpRequest();
            xhr.open("POST", url, true);
            xhr.setRequestHeader("Content-type", "application/json");
            xhr.onreadystatechange = () => {

                if (xhr.readyState == 4) {

                    if (xhr.status == 200) {

                        resolve(JSON.parse(xhr.responseText));
                    } else {

                        reject(xhr.responseText);
                    }
                }
            };
            xhr.send(JSON.stringify(dado)); // usando JSON.stringify para converter objeto em uma string no formato JSON.
        });

    }
}
<!-- aluraframe/client/post.html -->
<html>
<head>
    <meta charset="UTF-8">
    <title>Negociações</title>
    <link rel="stylesheet" href="css/bootstrap.css">
    <link rel="stylesheet" href="css/bootstrap-theme.css">
</head>

<body class="container">
    <form class="form">

        <div class="form-group">
            <label for="data">Data</label>
            <input type="date" id="data" class="form-control" required autofocus/>        
        </div>    

        <div class="form-group">
            <label for="quantidade">Quantidade</label>
            <input type="number" min="1" step="1" id="quantidade" class="form-control" value="1" required/>
        </div>

        <div class="form-group">
            <label for="valor">Valor</label>
            <input id="valor" type="number" class="form-control"  min="0.01" step="0.01" value="0.0" required />
        </div>

        <button class="btn btn-primary" type="submit" onclick="sendPost(event)">Enviar dados para servidor</button>
    </form>

    <script src="js/app/services/HttpService.js"></script>
    <script>
        function sendPost(event) {

            event.preventDefault();

            console.log("Enviando post");

            let $ = document.querySelector.bind(document);
            inputData = $('#data');
            inputQuantidade = $('#quantidade');
            inputValor = $('#valor');

            let negociacao = {
                data: inputData.value,
                quantidade: inputQuantidade.value,
                valor: inputValor.value
            };

            // usando nosso serviço. Veja que nem guardei em uma variável 
            new HttpService()
                .post('/negociacoes', negociacao)
                .then(() => {
                    inputData.value = '';
                    inputQuantidade.value = 1;
                    inputValor.value = 0.0;
                    inputData.focus();
                    alert('Negociação enviada com sucesso');
                })
                .catch(erro => alert(`Não foi possível enviar a negociação: ${erro}`));
        }
    </script>
</body>
</html>

Atenciosamente.

2 respostas

Fala Elías,

quando você nao passa todos o endereço e apenas o caminho 'negociacoes', veja q automaticamente sua chamada foi complementada com o protocolo file, 'file:///negociacoes',

esse endereço é então bloqueado como uma origem desconhecida e interpretada como segura e daí o error de CORS. Basicamente sua aplicação está dizendo, eu aceito requisições que venham de 'http://localhost:3000' pois sei q é seguro e einclusive estpu rodando nesse endereço, mas requisições de 'file:///' ou por exemplo 'http://localhost:8080' eu não aceito pois nao sei se são seguros.

Contudo, em outros cursos você verá que pode configurar uma lista de endereços para sua aplicação confiar

Olá Jefferson!

Obrigado pelas explicações.

Se você puder explicar mais uma parte que citei acima: porque para o instrutor (e pelo jeito para os demais colegas também) não ocorre(u) este erro com a url "/negociacoes" (usando esta url diretamente)...

Em relação à tua citação sobre cursos que ensinam a configuração de urls confiáveis, poderia indicar alguns?

Atenciosamente.

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