jquery - Por que meu JavaScript obtém um erro “No 'Access-Control-Allow-Origin' está presente no recurso solicitado” quando o Postman não?




15 Answers

Isso não é uma correção para produção ou quando o aplicativo precisa ser mostrado para o cliente, isso só é útil quando o desenvolvimento da UI e do Backend estão em servidores diferentes e na produção eles estão, na verdade, no mesmo servidor. Por exemplo: Ao desenvolver a interface do usuário para qualquer aplicativo, se houver necessidade de testá-lo localmente, apontando-o para o servidor de back-end, nesse cenário, essa é a correção perfeita. Para correção de produção, os cabeçalhos CORS devem ser adicionados ao servidor backend para permitir acesso de origem cruzada.

A maneira mais fácil é simplesmente adicionar a extensão no Google Chrome para permitir o acesso usando o CORS.

( https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?hl=en-US )

Basta ativar essa extensão sempre que você quiser permitir acesso a nenhuma solicitação de cabeçalho 'access-control-allow-origin' .

Ou

No Windows, cole este comando na janela de execução

chrome.exe --user-data-dir="C:/Chrome dev session" --disable-web-security

isso abrirá um novo navegador chrome que permite o acesso a nenhuma solicitação de cabeçalho 'access-control-allow-origin' .

jquery cors restful-authentication same-origin-policy flask-restless

Eu estou tentando fazer autorização usando JavaScript conectando-se à API RESTful construída no Flask . No entanto, quando faço a solicitação, recebo o seguinte erro:

XMLHttpRequest não pode carregar http: // myApiUrl / login . Nenhum cabeçalho 'Access-Control-Allow-Origin' está presente no recurso solicitado. A origem 'null' não tem, portanto, permissão de acesso.

Eu sei que a API ou recurso remoto deve definir o cabeçalho, mas por que funcionou quando fiz a solicitação por meio da extensão do Chrome Postman ?

Este é o código de solicitação:

$.ajax({
    type: "POST",
    dataType: 'text',
    url: api,
    username: 'user',
    password: 'pass',
    crossDomain : true,
    xhrFields: {
        withCredentials: true
    }
})
    .done(function( data ) {
        console.log("done");
    })
    .fail( function(xhr, textStatus, errorThrown) {
        alert(xhr.responseText);
        alert(textStatus);
    });



É muito simples de resolver se você estiver usando PHP . Basta adicionar o seguinte script no início da sua página PHP, que trata da solicitação:

<?php header('Access-Control-Allow-Origin: *'); ?>

Aviso: Isso contém um problema de segurança para o arquivo PHP que pode ser chamado por invasores. você tem que usar sessões e cookies para autenticação para prevenir seu arquivo / serviço contra este ataque. Seu serviço é vulnerável a falsificação de solicitações entre sites (CSRF).

Se você estiver usando o Node-red , deverá permitir o CORS no arquivo node-red/settings.js , deixando de comentar as seguintes linhas:

// The following property can be used to configure cross-origin resource sharing
// in the HTTP nodes.
// See https://github.com/troygoode/node-cors#configuration-options for
// details on its contents. The following is a basic permissive set of options:
httpNodeCors: {
 origin: "*",
 methods: "GET,PUT,POST,DELETE"
},



Se você estiver usando o Node.js , tente:

app.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    next();
});

Mais informações: CORS no ExpressJS




Porque
$ .ajax ({type: "POST" - OPÇÕES DE CHAMADAS
$ .post ( - chama o POST

ambos são diferentes Carteiro chama "POST" corretamente, mas quando nós o chamamos será "OPÇÕES"

Para c # web services - webapi

Por favor, adicione o seguinte código no seu arquivo web.config sob a tag <system.webServer>. Isso vai funcionar

<httpProtocol>
    <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
    </customHeaders>
</httpProtocol>

Por favor, verifique se você não está cometendo nenhum erro na chamada ajax

jQuery

$.ajax({
    url: 'http://mysite.microsoft.sample.xyz.com/api/mycall',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
    },
    type: "POST", /* or type:"GET" or type:"PUT" */
    dataType: "json",
    data: {
    },
    success: function (result) {
        console.log(result);    
    },
    error: function () {
        console.log("error");
    }
});

Angular 4 questão por favor consulte: http://www.hubfly.com/blog/solutions/how-to-fix-angular-4-api-call-issues/

Nota: Se você estiver procurando por download de conteúdo de um site de terceiros , isso não ajudará você . Você pode tentar o seguinte código, mas não o JavaScript.

System.Net.WebClient wc = new System.Net.WebClient();
string str = wc.DownloadString("http://mysite.microsoft.sample.xyz.com/api/mycall");



Se você não quiser:

  1. Desativar segurança da Web no Chrome
  2. Use JSONP
  3. Use um site de terceiros para redirecionar suas solicitações

e você tem certeza de que seu servidor tem o CORS ativado (teste o CORS aqui: http://www.test-cors.org/ )

Então você precisa passar no parâmetro de origem com o seu pedido. Esta origem DEVE corresponder à origem que o seu navegador envia com o seu pedido.

Você pode vê-lo em ação aqui: http://www.wikibackpacker.com/app/detail/Campgrounds/3591

A funcionalidade de edição envia uma solicitação GET & POST para um domínio diferente para buscar dados. Eu defino o parâmetro de origem que resolve o problema. O backend é um mecanismo do mediaWiki.

tldr: Adicione o parâmetro "origin" às suas chamadas, que deve ser o parâmetro Origin que o seu navegador envia (você não pode falsificar o parâmetro de origem)




Eu tive a seguinte configuração, resultando no mesmo erro, ao solicitar respostas do servidor.

Do lado do servidor: SparkJava -> fornece a API REST
Lado do cliente: ExtJs6 -> fornece renderização do navegador

No lado do servidor eu tive que adicionar isso à resposta:

Spark.get("/someRestCallToSpark", (req, res) -> {
    res.header("Access-Control-Allow-Origin", "*"); //important, otherwise its not working 
    return "some text";
 });

No lado do cliente eu tive que adicionar isso ao pedido:

Ext.Ajax.request({
    url: "http://localhost:4567/someRestCallToSpark",
    useDefaultXhrHeader: false, //important, otherwise its not working
    success: function(response, opts) {console.log("success")},
    failure: function(response, opts) {console.log("failure")}
});



Você pode contornar o problema usando o YQL para fazer proxy do pedido através dos servidores do Yahoo. São apenas algumas linhas de código:

var yql_url = 'https://query.yahooapis.com/v1/public/yql';
var url = 'your api url';

$.ajax({
    'url': yql_url,
    'data': {
        'q': 'SELECT * FROM json WHERE url="'+url+'"',
        'format': 'json',
        'jsonCompat': 'new',
    },
    'dataType': 'jsonp',
    'success': function(response) {
        console.log(response);
    },
});

Aqui está o link com uma explicação: https://vverma.net/fetch-any-json-using-jsonp-and-yql.html




Se você estiver usando o Entity Framework , parece que esse erro algumas vezes será lançado mesmo se você tiver o CORS habilitado. Eu descobri que o erro ocorreu devido a uma falta de finalização da consulta. Espero que isso ajude os outros na mesma situação.

O seguinte código pode lançar o XMLHttpRequest cannot load http://myApiUrl/login. No 'Access-Control-Allow-Origin' header is present on the requested resource. XMLHttpRequest cannot load http://myApiUrl/login. No 'Access-Control-Allow-Origin' header is present on the requested resource. erro:

using (DBContext db = new DBContext())
{
    return db.Customers.Select(x => new
    {
        Name = x.Name,
        CustomerId = x.CustomerId,
    });
}

Para corrigi-lo, uma chamada de finalização como .ToList() ou .FirstOrDefault() no final da consulta é necessária, assim:

using (DBContext db = new DBContext())
{
    return db.Customers.Select(x => new
    {
        Name = x.Name,
        CustomerId = x.CustomerId,
    }).ToList();
}



Consegui resolver com sucesso (no meu caso, para fontes) usando o htaccess, mas, obviamente, OP está pedindo pouco diferente. Mas você pode usar o padrão FileMatch e adicionar qualquer tipo de extensão para que não ocorra erro.

<IfModule mod_headers.c>
  <FilesMatch "\.(ttf|ttc|otf|eot|woff|woff2|font.css|css)$">
    Header set Access-Control-Allow-Origin "*"
  </FilesMatch>
</IfModule>

https://httpd.apache.org/docs/2.4/mod/core.html#filesmatch




Para a API do GoLang:

Primeiro você pode dar uma olhada no MDN CORS Doc para saber o que é o CORS. Até onde eu sei, o CORS é sobre permitir que o Origin Of Request acesse ou não o Recurso do Servidor.

E você pode restringir qual origem da solicitação pode acessar o servidor definindo Access-Control-Allow-Origin no Header da resposta do servidor.

Por exemplo, definir o seguinte cabeçalho na resposta do servidor significa que apenas a solicitação enviada de http://foo.example pode acessar seu servidor:

Access-Control-Allow-Origin: http://foo.example

e seguindo pedido de permissão enviado de qualquer origem (ou domínio):

Access-Control-Allow-Origin: *

E como eu sei na mensagem de erro, requested resource significa recurso do servidor, portanto, No 'Access-Control-Allow-Origin' header is present on the requested resource. significa que você não definiu o cabeçalho Access-Control-Allow-Origin em sua resposta do servidor, ou talvez você definiu, mas a origem da solicitação não está listada em Access-Control-Allow-Origin portanto a solicitação não tem permissão de acesso:

Nenhum cabeçalho 'Access-Control-Allow-Origin' está presente no recurso solicitado. A origem 'null' não tem, portanto, permissão de acesso.

No GoLang, eu uso o pacote gorilla/mux para construir o servidor de API no localhost:9091 , e permito que o CORS adicione "Access-Control-Allow-Origin", "*" ao cabeçalho da resposta:

func main() { // API Server Code
    router := mux.NewRouter()
    // API route is /people,
    //Methods("GET", "OPTIONS") means it support GET, OPTIONS
    router.HandleFunc("/people", GetPeople).Methods("GET", "OPTIONS")
    log.Fatal(http.ListenAndServe(":9091", router))
}

// Method of '/people' route
func GetPeople(w http.ResponseWriter, r *http.Request) {

    // Allow CORS by setting * in sever response
    w.Header().Set("Access-Control-Allow-Origin", "*")

    w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
    json.NewEncoder(w).Encode("OKOK")
}

E eu uso JavaScript no cliente, em localhost:9092 fazer pedido pelo Chrome pode obter com êxito "OKOK" do servidor localhost:9091 .

function GetPeople() {
    try {
        var xhttp = new XMLHttpRequest();
        xhttp.open("GET", "http://localhost:9091/people", false);
        xhttp.setRequestHeader("Content-type", "text/html");
        xhttp.send();
        var response = JSON.parse(xhttp.response);
        alert(xhttp.response);
    }
    catch (error) {
        alert(error.message);
    }
}

Além disso, você pode verificar o seu pedido / resposta cabeçalho por ferramentas como Fiddler.




Muitas vezes isso acontece comigo de javascript para o meu php api, porque um dos poucos motivos. Eu esqueço de colocar o <?php header('Access-Control-Allow-Origin: *'); ?é um. Isso é útil para o acesso de subdomínio cruzado. Outra razão, é porque no pedido ajax do jQuery eu estou especificando um dataType específico e retornando um dataType diferente, então ele gera um erro.

O último e mais proeminente raciocínio para esse erro é que há um erro de análise na página que você está solicitando. Se você acertar o URL da página no seu navegador, provavelmente verá um erro de análise e terá um número de linha para resolver o problema.

Espero que isso ajude alguém. Levei um tempo a cada vez para depurar isso e gostaria de ter uma lista de coisas para verificar.




CORS é para você.

O CORS é "Compartilhamento de recursos de origem cruzada" e é uma maneira de enviar uma solicitação de domínio cruzado. Agora, as API XMLHttpRequest2 e Fetch suportam o CORS.

Mas tem seus limites. O servidor precisa reivindicar especificamente o Access-Control-Allow-Origin e não pode ser definido como '*'.

E se você quiser que qualquer origem possa enviar uma solicitação para você, você precisa de JSONP (também precisa definir Access-Control-Allow-Origin , mas pode ser '*').

Para muitos pedidos, se você não sabe o que escolher, eu acho que você precisa de um componente totalmente funcional para fazer isso. Deixe-me apresentar um componente simples catta

Se você estiver usando um navegador moderno (> Internet Explorer9, Chrome, Firefox, Edge, etc.), é muito recomendado que você use um componente simples, mas bonito, catta . Ele não tem dependências, é menor que 3 KB e suporta Fetch, Ajax e JSONP com a mesma sintaxe e opções dead-simple.

catta('./data/simple.json').then(function (res) {
  console.log(res);
});

Ele também suporta todo o caminho para importar para o seu projeto, como módulo ES6, CommonJS e até mesmo <script>em HTML.




No meu site (baseado no .NET), acabei de adicionar isto:

<system.webServer>
 <httpProtocol>  
    <customHeaders>  
     <add name="Access-Control-Allow-Origin" value="*" />  
     <add name="Access-Control-Allow-Headers" value="Content-Type" />  
     <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />  
    </customHeaders>  
  </httpProtocol>         
</system.webServer>

Muito obrigado a this vídeo.




Nenhum cabeçalho 'Access-Control-Allow-Origin' está presente no recurso solicitado. A origem ' https://sx.xyz.com ' não tem, portanto, acesso permitido.

Eu também havia enfrentado um problema semelhante com o Cross Domain Data Exchange na resposta do Ajax como erro indefinido . Mas a resposta no cabeçalho foi Código de Status: 200 OK

Failed to load https://www.Domain.in/index.php?route=api/synchronization/checkapikey:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'https://sx.xyz.in' is therefore not allowed access.

A solução para contorná-lo: No meu caso, foi chamar a função checkapikey () via Ajax para outro domínio e obter a resposta com os dados para onde a chamada foi feita:

if (($this->request->server['REQUEST_METHOD'] == 'POST') && isset($this->request->server['HTTP_ORIGIN'])) {

        $this->response->addHeader('Access-Control-Allow-Origin: ' . $this->request->server['HTTP_ORIGIN']);
        $this->response->addHeader('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
        $this->response->addHeader('Access-Control-Max-Age: 1000');
        $this->response->addHeader('Access-Control-Allow-Credentials: true');
        $this->response->addHeader('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With');

        $headers = getallheaders();
...
}



Talvez seja um pouco complicado, mas você pode usar um servidor web para encaminhar a solicitação. Com o nodejs você não tem esse problema. Eu não sou um especialista em nó js. Então eu não sei se isso é código limpo.

Mas isso funciona para mim

Aqui está um pequeno exemplo:

NODE JS

var rp = require('request-promise');
var express = require('express'),
    app = express(),
    port = process.env.PORT || 3000;
var options = {
    method: 'POST',
    uri: 'http://api.posttestserver.com/post',
    body: {
        some: 'payload'
    },
    json: true // Automatically stringifies the body to JSON
};
app.get('/', function (req, res) {
        rp(options)
        .then(function (parsedBody) {
            res.send(parsedBody)
        })
        .catch(function (err) {
            res.send(err)
        });
});
app.listen(port);

JS

axios.get("http://localhost:3000/").then((res)=>{
    console.log('================res====================');
    console.log(res);
    console.log('====================================');
})



Related