Nenhum cabeçalho 'Access-Control-Allow-Origin' está presente no recurso solicitado. Portanto, a origem '…' não é permitida

135

Estou usando .htaccess para reescrever URLs e usei a tag base html para fazê-lo funcionar.

Agora, quando tento fazer uma solicitação ajax, recebo o seguinte erro:

XMLHttpRequest não pode carregar http://www.example.com/login.php. Nenhum cabeçalho 'Access-Control-Allow-Origin' está presente no recurso solicitado. http://example.comPortanto, a origem ' ' não é permitida.

Th3lmuu90
fonte
1
Deixa pra
8
Embora sutil, http://wordicious.comé um domínio diferente do que http://www.wordicious.com/, portanto, o erro. Btw, se está funcionando agora e voltou por si só, você provavelmente deve excluir a pergunta.
Acdcjunior 6/12/2013
@acdcjunior Esse parece ser o erro, que é uma observação astuta da sua parte. Se você postar isso como uma resposta, eu a aprovaria.
Waleed Khan
5
É bom que a pergunta não tenha sido excluída, ou eu não a teria visto hoje!
icedwater

Respostas:

170

Use addHeaderEm vez de usar o setHeadermétodo,

response.addHeader("Access-Control-Allow-Origin", "*");

*na linha acima permitirá access to all domains.


Por permitir access to specific domain only:

response.addHeader("Access-Control-Allow-Origin", "http://www.example.com");

Verifique isso blog post.

Jay Patel
fonte
4
está mostrando addheader não definido. Você pode por favor explicar?
Vaisakh Pc
9
Onde coloco essas linhas?
DaveWalley
14
Onde isso deve ser adicionado?
31414 Alex
1
Essa postagem do blog está falando sobre o Node.js e o express. Não é javascript do lado do cliente. alguém pode confirmar se isso funciona?
Sam Eaton
1
Eu não acho que esta configuração pode ser feito apenas no lado do cliente .. Assim como para onde colocá-lo, seria no código do lado do servidor (presumivelmente na construção de uma resposta a um pedido)
Chirag Ravindra
145

Por que o erro foi gerado:

O código JavaScript é limitado pela política de mesma origem , ou seja, a partir de uma página em www.example.com, você só pode fazer solicitações (AJAX) para serviços localizados exatamente no mesmo domínio, nesse caso, exatamente www.example.com( não example.com - sem o www- ou whatever.example.com).

No seu caso, seu código Ajax está tentando acessar um serviço a http://wordicious.compartir de uma página localizada em http://www.wordicious.com.

Embora muito parecidos, eles não são do mesmo domínio. E quando eles não estiverem no mesmo domínio, a solicitação só será bem-sucedida se a resolução do destino contiver um Access-Control-Allow-Origincabeçalho.

Como sua página / serviço em http://wordicious.comnunca foi configurada para apresentar esse cabeçalho, essa mensagem de erro é mostrada.

Solução:

Como dito, os domínios de origem (onde a página com JavaScript está) e o destino (onde o JavaScript está tentando alcançar) devem ser exatamente os mesmos.

Seu caso parece um erro de digitação. Parece http://wordicious.come http://www.wordicious.comé realmente o mesmo servidor / domínio. Portanto, para corrigir, digite o destino e a origem igualmente: faça com que você solicite páginas / serviços de código Ajax para http://www.wordicious.comnãohttp://wordicious.com . (Talvez coloque o URL de destino relativamente, tipo '/login.php', sem o domínio).



Em uma nota mais geral:

Se o problema não for um erro de digitação, como parece ser o desta pergunta, a solução seria adicionar o Access-Control-Allow-Origindomínio de destino . Para adicioná-lo, depende, é claro, do servidor / idioma por trás desse endereço. Às vezes, uma variável de configuração na ferramenta faz o truque. Outras vezes, você precisará adicionar os cabeçalhos através do código.

acdcjunior
fonte
62

Para o servidor .NET, você pode configurar isso em web.config, como mostrado abaixo

 <system.webServer>
   <httpProtocol>
     <customHeaders>
       <add name="Access-Control-Allow-Origin" value="your_clientside_websiteurl" />
     </customHeaders>
   </httpProtocol>
 </system.webServer>

Por exemplo, digamos que, se o domínio do servidor for http://live.makemypublication.com e o cliente for http://www.makemypublication.com , configure no web.config do servidor como abaixo

 <system.webServer>
   <httpProtocol>
     <customHeaders>
       <add name="Access-Control-Allow-Origin" value="http://www.makemypublication.com" />
     </customHeaders>
  </httpProtocol>
 </system.webServer>
Naga
fonte
Uma solução ainda melhor. Obrigado
ANJYR - KODEXPRESSION
Muito obrigado. Você salvou meu dia inteiro.
Prateek Gupta
Trabalhando mesmo depois de 2 anos: p
Ubiquitous Developers
1
@SyedAliTaqi a pergunta é php, é por isso que a resposta é subestimada. no entanto, ele trabalhou para mim também :)
Ahmad Th
22

Se você receber esta mensagem de erro do navegador:

Nenhum cabeçalho 'Access-Control-Allow-Origin' está presente no recurso solicitado. Portanto, a origem '…' não é permitida

quando você estiver tentando fazer uma solicitação Ajax POST / GET para um servidor remoto que esteja fora de seu controle, esqueça esta simples correção:

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

O que você realmente precisa fazer, especialmente se você usa JavaScript apenas para fazer a solicitação do Ajax, é um proxy interno que pega sua consulta e a envia para o servidor remoto.

Primeiro no seu JavaScript, faça uma chamada do Ajax para o seu próprio servidor, algo como:

$.ajax({
    url: yourserver.com/controller/proxy.php,
    async:false,
    type: "POST",
    dataType: "json",
    data: data,
    success: function (result) {
        JSON.parse(result);
    },
    error: function (xhr, ajaxOptions, thrownError) {
        console.log(xhr);
    }
});

Em seguida, crie um arquivo PHP simples chamado proxy.php para agrupar seus dados do POST e anexá-los ao servidor de URL remoto como parâmetro. Dou um exemplo de como ignoro esse problema com a API de pesquisa do hotel Expedia:

if (isset($_POST)) {
  $apiKey = $_POST['apiKey'];
  $cid = $_POST['cid'];
  $minorRev = 99;

  $url = 'http://api.ean.com/ean-services/rs/hotel/v3/list?' . 'cid='. $cid . '&' . 'minorRev=' . $minorRev . '&' . 'apiKey=' . $apiKey;

  echo json_encode(file_get_contents($url));
 }

Fazendo:

 echo json_encode(file_get_contents($url));

Você está apenas fazendo a mesma consulta, mas no lado do servidor e depois disso, deve funcionar bem.

Nizar B.
fonte
@NizarBsb você é louco, você sabe disso !!!!! : D, muito obrigado a sua resposta salvou minha vida
o Flash
10

Você precisa adicionar isso no início da sua página php "login.php"

<?php header('Access-Control-Allow-Origin: *'); ?>
Shady Sherif
fonte
5
Definitivamente não é seguro.
callback
7

você deve colocar as chaves / valores dos cabeçalhos na resposta do método de opções. por exemplo, se você tiver recurso em http://mydomain.com/myresource , no código do servidor você escreve

//response handler
void handleRequest(Request request, Response response) {
    if(request.method == "OPTIONS") {
       response.setHeader("Access-Control-Allow-Origin","http://clientDomain.com")
       response.setHeader("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS");
       response.setHeader("Access-Control-Allow-Headers", "Content-Type");
    }



}
i-systech.com
fonte
3

Altere basicamente a resposta do cabeçalho da API adicionando os seguintes parâmetros adicionais.

Access-Control-Allow-Credentials: true

Controle de Acesso - Permitir Origem: *

Mas essa não é uma boa solução quando se trata de segurança

Piusha
fonte
3

A solução alternativa é usar um proxy reverso em execução no host 'de origem' e encaminhar para o servidor de destino, como o Fiddler:

Link aqui: http://docs.telerik.com/fiddler/configure-fiddler/tasks/usefiddlerasreverseproxy

Ou um proxy reverso do Apache ...

hzrari
fonte
Isso pode ser feito no nível de configuração do Apache ou Nginx para um domínio. por exemplo, se um usuário estiver acessando mysite.com (sem www) e o XHR solicitar www.mysite.com, uma diretiva htaccess ou httpd.conf pode resolver isso?
Codecowboy
Claro, seu aplicativo front-end deve se comportar como um proxy reverso. por exemplo, para o Apache, você precisa instalar o mod_proxy e configurar suas regras usando o ProxyPassReverse ( httpd.apache.org/docs/current/mod/… ). As mesmas características parece ser availabe em Nginx também: wiki.nginx.org/LikeApache
hzrari
2

Adicione isso ao seu arquivo PHP ou controlador principal

header("Access-Control-Allow-Origin: http://localhost:9000");
Sam
fonte
para finalizar - você também precisa #header("Access-Control-Allow-Credentials: true");
Adam
1

Resolvido com a entrada abaixo no httpd.conf

#CORS Issue
Header set X-Content-Type-Options "nosniff"
Header always set Access-Control-Max-Age 1728000
Header always set Access-Control-Allow-Origin: "*"
Header always set Access-Control-Allow-Methods: "GET,POST,OPTIONS,DELETE,PUT,PATCH"
Header always set Access-Control-Allow-Headers: "DNT,X-CustomHeader,Keep-Alive,Content-Type,Origin,Authentication,Authorization,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control"
Header always set Access-Control-Allow-Credentials true

#CORS REWRITE
RewriteEngine On                  
RewriteCond %{REQUEST_METHOD} OPTIONS 
#RewriteRule ^(.*)$ $1 [R=200,L]
RewriteRule ^(.*)$ $1 [R=200,L,E=HTTP_ORIGIN:%{HTTP:ORIGIN}]]
Sandeep540
fonte
A única maneira que trabalhou para mim em Apache2, CentOS7, Larravel 5, e reagir
Shakiba Moshiri