CORS mortal quando http: // localhost é a origem

186

Estou com esse problema do CORS, apesar de definir o servidor (nginx / node.js) com os cabeçalhos apropriados.

Eu posso ver no painel Rede do Chrome -> Cabeçalhos de resposta:

Access-Control-Allow-Origin:http://localhost

o que deve fazer o truque.

Aqui está o código que agora uso para testar:

var xhr = new XMLHttpRequest();
xhr.onload = function() {
   console.log('xhr loaded');
};
xhr.open('GET', 'http://stackoverflow.com/');
xhr.send();

eu recebo

XMLHttpRequest não pode carregar http://stackoverflow.com/ . Origem http: // localhost não é permitido pelo Access-Control-Allow-Origin.

Eu suspeito que é um problema no script do cliente e não na configuração do servidor ...

whadar
fonte
44
Não, o stackoverflow.com precisa definir esse cabeçalho, não você. : x. Qual seria o ponto da mesma política de origem caso contrário.
Esailija
3
Tente acessar o servidor que você configurou para não sobrecarregar a pilha. ;)
Nek
DOH! Existe uma maneira de dizer ao chrome (ou outro navegador) para obter o recurso, mesmo se o cabeçalho estiver ausente quando minha origem for localhost?
Whadar
Execute seus códigos no Chrome (20.0.1132.57, Windows 7), funciona bem.
Imgilsonxu>
1
Se você estiver usando o host local com uma porta, esta resposta funcionou para mim serverfault.com/a/673551/238261 .
Nelu 23/09

Respostas:

230

O Chrome não suporta host local para solicitações do CORS (um bug aberto em 2010, marcado WontFix em 2014).

Para contornar isso, você pode usar um domínio como lvh.me(que aponta para 127.0.0.1 como localhost) ou iniciar o chrome com a --disable-web-securityflag (assumindo que você está apenas testando).

Beau
fonte
24
@greensuisse - não está sendo publicado no localhost. Está postando do localhost que é o problema.
Cheeso
9
Esse bug é inválido (e foi marcado como tal - crbug.com/67743#c17 ). O comentário de Esailija está correto, adicionar esses cabeçalhos ao host local não dará magicamente o acesso a todos os outros sites. É o site remoto que precisa ser veiculado com esses cabeçalhos.
22414 Rob Rob W
22
Apenas passamos 2 horas testando no Chrome para perceber que ele funciona perfeitamente bem no Firefox ..Grrrr...
FloatingRock
11
. Outra opção: editar o seu arquivo hosts para que locais [mysite] .com aponta para 127.0.0.1, em seguida, fazer o seu arquivo CORS permitirá * [mysite] .com.
Tom
6
Eu enfrentei o mesmo problema com o FireFox. Eu só consegui chegar no Edge! Bom post, porém, fantástico! :)
Luis Gouveia
54

De acordo com a resposta do @ Beau, o Chrome não suporta solicitações CORS do host local e é improvável que haja alguma alteração nessa direção.

Eu uso o Allow-Control-Allow-Origin: * Extensão do Chrome para solucionar esse problema. A extensão adicionará os cabeçalhos HTTP necessários para o CORS:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: "GET, PUT, POST, DELETE, HEAD, OPTIONS"
Access-Control-Expose-Headers: <you can add values here>

O código fonte é publicado no Github .

Observe que a extensão filtra todos os URLs por padrão. Isso pode quebrar alguns sites (por exemplo: Dropbox). Alterei-o para filtrar apenas URLs de host local com o seguinte filtro de URL

*://localhost:*/*
Hanxue
fonte
14
Se você ler o problema nos links @beau, verá que o Chrome 100% suporta solicitações de origem cruzada de e para host local. O problema foi encerrado em 2014 porque não pôde ser reproduzido. O restante do ruído nesse encadeamento é de pessoas com servidores de origem não configurados incorretamente (como na pergunta original aqui).
Molomby 5/03/19
1
Trabalhou como charme para mim no Chrome
Aakash Sahai
3
Que esta extensão não funcionar com Access-Control-Allow-Credentials: trueporque ele define Access-Control-Allow-Originpara *e com ambas truee *é bloqueada pelos navegadores. Se estiver usando credenciais true, você deve usar a origem não curinga. Eu recomendo o Moesif Origins e o CORS Changer Extension, que permitem alterar os cabeçalhos da maneira que desejar.
Samuel
Talvez eu esteja fazendo algo errado, mas essa extensão não parece mais funcionar para mim.
James Parker
19

O verdadeiro problema é que, se definirmos -Allow-para todas as solicitações ( OPTIONS& POST), o Chrome a cancelará. O código a seguir funciona para mim POSTno LocalHost com Chrome

<?php
if (isset($_SERVER['HTTP_ORIGIN'])) {
    //header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}");
    header("Access-Control-Allow-Origin: *");
    header('Access-Control-Allow-Credentials: true');    
    header("Access-Control-Allow-Methods: GET, POST, OPTIONS"); 
}   
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']))
        header("Access-Control-Allow-Methods: GET, POST, OPTIONS");         
    if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']))
        header("Access-Control-Allow-Headers:{$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}");

    exit(0);
} 
?>
greensuisse
fonte
15
O OP está usando o nginx / node.js. Não PHP
code_monk
4

O Chrome fará solicitações com o CORS de uma localhostorigem muito bem. Este não é um problema com o Chrome.

O motivo pelo qual você não pode carregar http://stackoverflow.comé que os Access-Control-Allow-Origincabeçalhos não estavam permitindo sua localhostorigem.

Brad
fonte
2

Correção de extensão rápida e suja do Chrome:

Moesif Orign & CORS Changer

No entanto, o Chrome suporta solicitações de origem cruzada do host local. Certifique-se de adicionar um cabeçalho para Access-Control-Allow-Originfor localhost.

kaleazy
fonte
Eu adicionei esta extensão ao meu Opera e agora está pronto. Eu nunca posso dizer quando é ligado e desligado, então eu uso o Firefox para o trabalho. e ópera para o desenvolvimento. O Google Suit não gosta, e outras coisas também não.
quer
1

Nenhuma das extensões funcionou para mim, então instalei um proxy local simples. No meu caso, https://www.npmjs.com/package/local-cors-proxy É uma configuração de 2 minutos:

(do site deles)

npm install -g local-cors-proxy

Terminal da API que queremos solicitar que tenha problemas com o CORS: https://www.yourdomain.ie/movies/list

Iniciar Proxy: lcp --proxyUrl https://www.yourdomain.ie

Em seguida, no código do cliente, novo ponto de extremidade da API: http://localhost:8010/proxy/movies/list

Funcionou como um encanto para mim: seu aplicativo chama o proxy, que chama o servidor. Zero problemas de CORS.

daniel p
fonte
0

Decidi não tocar nos cabeçalhos e fazer um redirecionamento no lado do servidor e ele funciona como um encanto.

O exemplo abaixo é para a versão atual do Angular (atualmente 9) e provavelmente qualquer outra estrutura usando os DevServer dos webpacks. Mas acho que o mesmo princípio funcionará em outros back-ends.

Então, eu uso a seguinte configuração no arquivo proxy.conf.json :

{
  "/api": {
    "target": "http://localhost:3000",
    "pathRewrite": {"^/api" : ""},
   "secure": false
 }
}

No caso do Angular, eu sirvo com essa configuração:

$ ng serve -o --proxy-config=proxy.conf.json

Eu prefiro usar o proxy no comando serve, mas você também pode colocar essa configuração em angular.json assim:

"architect": {
  "serve": {
    "builder": "@angular-devkit/build-angular:dev-server",
    "options": {
      "browserTarget": "your-application-name:build",
      "proxyConfig": "src/proxy.conf.json"
    },

Veja também:

https://www.techiediaries.com/fix-cors-with-angular-cli-proxy-configuration/

https://webpack.js.org/configuration/dev-server/#devserverproxy

Juri Sinitson
fonte