A origem não é permitida pelo Access-Control-Allow-Origin


337

Estou criando um Ajax.requestservidor PHP remoto em um aplicativo Sencha Touch 2 ( incluído no PhoneGap ).

A resposta do servidor é a seguinte:

XMLHttpRequest não pode carregar http://nqatalog.negroesquisso.pt/login.php . A origem http://localhost:8888não é permitida pelo Access-Control-Allow-Origin.

Como posso resolver este problema?


19
enquanto estiver usando jQuery, ajuste dataType: 'jsonp',faz o truque
— Amit

11
pela maneira que não é a resposta do servidor. Para ser preciso, esse erro é emitido no lado do cliente.
— Matteo

2
O truque jsonp provavelmente não funciona mais, fyi: stackoverflow.com/questions/12216208/...
— drewww

7
Observe que desde que perdi meio dia perseguindo esse bug - Se o script do lado do servidor falhar com um erro interno do servidor, o navegador poderá interpretá-lo como se a solicitação não fosse permitida devido Access-Control-Allow-Origine reportar isso como erro.
— troelskn 02/09

11
@troelskn Você acabou de salvar minha vida. Eu estava procurando por algum erro de CORS desde 3 dias, e era simplesmente um pequeno problema de configuração do Spring causando um 500, que eu resolvi em 5 minutos depois de ler seu comentário e realmente o procurei. Obrigado!
— Alexis Dufrenoy

Respostas:


378

Escrevi um artigo sobre esse assunto há algum tempo, Cross Domain AJAX .

A maneira mais fácil de lidar com isso se você tiver controle do servidor de resposta é adicionar um cabeçalho de resposta para:

Access-Control-Allow-Origin: *

Isso permitirá que o Ajax entre domínios . No PHP, você deseja modificar a resposta da seguinte maneira:

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

Você pode simplesmente colocar a Header set Access-Control-Allow-Origin *configuração na configuração do Apache ou no arquivo htaccess.

Deve-se observar que isso desativa efetivamente a proteção CORS, o que provavelmente expõe seus usuários a ataques . Se você não sabe que precisa especificamente usar um curinga, não deve usá-lo e, em vez disso, deve colocar seu domínio específico na lista de permissões:

<?php header('Access-Control-Allow-Origin: http://example.com') ?>

4
Vou entrar em contato com meu provedor de servidores. Obrigado
— Ricardo

8
Há alguma preocupação de segurança com isso? Esta resposta , por exemplo, diz "O JavaScript é limitado pela" mesma política de origem "por motivos de segurança. Por exemplo, um script malicioso não pode entrar em contato com um servidor remoto e enviar dados confidenciais do seu site".
— JohnK

4
Incrível, acabei de colocar isso no meu arquivo do servidor node.js.: response.writeHead (200, {'Content-Type': contentType, 'Access-Control-Allow-Origin': '*'}); E funcionou. Obrigado!
— vbullinger

25
JohnK, sim, o curinga permitirá que qualquer domínio envie solicitações ao seu host. Eu recomendo substituir o asterisco por um domínio específico no qual você executará scripts.
— Nick

7
É interessante que você ache que o curinga nem deveria ser sugerido @jfrej. Tudo depende do seu objetivo. Por exemplo, o motivo pelo qual usamos o curinga (e postamos esta resposta) foi porque estávamos construindo um widget incorporado para qualquer site usar.
— Matt Mombrea

63

Se você não tem o controle do servidor, você pode simplesmente adicionar este argumento para seu lançador Chrome: --disable-web-security.

Note que eu não usaria isso para "navegação na web" normal. Para referência, consulte esta postagem: Desative a mesma política de origem no Chrome .

Se você usar o Phonegap para criar o aplicativo e carregá-lo no dispositivo, isso não será um problema.


Obrigado. Mas meu aplicativo está sendo executado em dispositivos móveis, não posso passar argumentos para o meu wrapper de visualização na web.
— Ricardo

Você não testa seu aplicativo em um navegador primeiro? Como você depura?
— Travis Webb

Sim, eu depuro em um navegador Chrome, mas o aplicativo não roda no chrome. Será no phonegap webview que eu não posso controlar.
— Ricardo

4
leia a resposta: você pode simplesmente adicionar esse argumento ao seu iniciador do Chrome . Não há nenhuma configuração para isso dentro do Chrome
— Travis Webb

2
Claro que é inseguro. O OP está pedindo uma maneira de contornar as medidas de segurança.
— Travis Webb

42

Se você estiver usando o Apache, basta adicionar:

<ifModule mod_headers.c>
    Header set Access-Control-Allow-Origin: *
</ifModule>

na sua configuração. Isso fará com que todas as respostas do seu servidor da Web sejam acessíveis a partir de qualquer outro site na Internet. Se você pretende permitir apenas que os serviços em seu host sejam usados ​​por um servidor específico, substitua-o *pelo URL do servidor de origem:

Header set Access-Control-Allow-Origin: http://my.origin.host

3
E não se esqueça de carregar o módulo: a2enmod cabeçalhos
— Walery Strauch

como carregar module: a2enmod headers?
— precisa

18

Se você tiver um aplicativo ASP.NET / ASP.NET MVC , poderá incluir esse cabeçalho através do arquivo Web.config:

<system.webServer>
  ...

    <httpProtocol>
        <customHeaders>
            <!-- Enable Cross Domain AJAX calls -->
            <remove name="Access-Control-Allow-Origin" />
            <add name="Access-Control-Allow-Origin" value="*" />
        </customHeaders>
    </httpProtocol>
</system.webServer>

2
Pessoal do .NET MVC, OLHE aqui! Na verdade, vou digitar uma solução e apontar para essa resposta no meu blog para que as pessoas possam encontrá-la mais fácil. Nada pior do que tentar superar um obstáculo .NET / MVC e encontrar apenas soluções PHP / jQuery. Obrigado @ Caio-Proiete
— ottoflux

11
Como isso não funciona para mim? Estou usando o Chrome e tentando acessar a página de finanças do yahoo no meu host local.
— New7 de

11
obrigado funcionou para mim. Eu adicionei no projeto de código do lado do servidor (web.config).
— Ethem

15

Esta foi a primeira pergunta / resposta que surgiu para mim ao tentar resolver o mesmo problema usando o ASP.NET MVC como a fonte dos meus dados. Sei que isso não resolve o PHP questão , mas está relacionado o suficiente para ser valioso.

Estou usando o asp.net MVC. O post de Greg Brant funcionou para mim. Por fim, você cria um atributo, [HttpHeaderAttribute("Access-Control-Allow-Origin", "*")]que pode adicionar às ações do controlador.

Por exemplo:

public class HttpHeaderAttribute : ActionFilterAttribute
{
    public string Name { get; set; }
    public string Value { get; set; }
    public HttpHeaderAttribute(string name, string value)
    {
        Name = name;
        Value = value;
    }

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        filterContext.HttpContext.Response.AppendHeader(Name, Value);
        base.OnResultExecuted(filterContext);
    }
}

E depois usá-lo com:

[HttpHeaderAttribute("Access-Control-Allow-Origin", "*")]
public ActionResult MyVeryAvailableAction(string id)
{
    return Json( "Some public result" );
}

11
O WebApi 2 incorporou isso agora. asp.net/web-api/overview/security/…
— Matt Frear

10

Como Matt Mombrea está correto para o lado do servidor, você pode encontrar outro problema que é a rejeição da lista de permissões.

Você precisa configurar seu phonegap.plist. (Estou usando uma versão antiga do phonegap)

Para cordova, pode haver algumas alterações no nome e no diretório. Mas as etapas devem ser basicamente as mesmas.

Primeiro selecione Arquivos de suporte> PhoneGap.plist

insira a descrição da imagem aqui

depois em "ExternalHosts"

Adicione uma entrada, com um valor de talvez " http://nqatalog.negroesquisso.pt ". Estou usando * apenas para fins de depuração.

insira a descrição da imagem aqui


8

Isso pode ser útil para quem precisa de uma exceção para as versões 'www' e 'não www' de um referenciador:

 $referrer = $_SERVER['HTTP_REFERER'];
 $parts = parse_url($referrer);
 $domain = $parts['host'];

 if($domain == 'google.com')
 {
         header('Access-Control-Allow-Origin: http://google.com');
 }
 else if($domain == 'www.google.com')
 {
         header('Access-Control-Allow-Origin: http://www.google.com');
 }

Apontou-me na direção certa para resolver o erro ACAO com o azure. Enquanto eu adicionava o nome de host permitido do googledrive. O URL usado precisa ser googledrive NÃO googledrive
— Kildareflare

7

Vou lhe dar uma solução simples para este. No meu caso, não tenho acesso a um servidor. Nesse caso, você pode alterar a política de segurança no seu navegador Google Chrome para permitir acesso-controle-permissão-origem. Isto é muito simples:

  1. Crie um atalho do navegador Chrome
  2. Clique com o botão direito do mouse no ícone de atalho -> Propriedades -> Atalho -> Alvo

Colar simples "C:\Program Files\Google\Chrome\Application\chrome.exe" --allow-file-access-from-files --disable-web-security.

A localização pode ser diferente. Agora abra o Chrome clicando nesse atalho.


7

Eu me deparei com isso algumas vezes ao trabalhar com várias APIs. Geralmente, uma solução rápida é adicionar "& callback =?" até o final de uma string. Às vezes, o "e comercial" precisa ser um código de caractere e, às vezes, um "?": "? Callback =?" (consulte Uso da API Forecast.io com jQuery )


6

Se você estiver escrevendo uma extensão do Chrome e obter este erro, então não se esqueça de adicionar URL base da API para o seu manifest.json's permissões bloco , exemplo:

"permissions": [
    "https://itunes.apple.com/"
]

6

Isso ocorre devido à política de mesma origem . Veja mais em Mozilla Developer Network ou Wikipedia .

Basicamente, no seu exemplo, você precisa carregar a http://nqatalog.negroesquisso.pt/login.phppágina apenas de nqatalog.negroesquisso.pt, não localhost.


11
Mas preciso carregar o serviço da web a partir de um dispositivo móvel, eu ignoraria isso?
— Ricardo

Bem, você precisa fazer algumas alterações do lado do servidor ou usar JSONP en.wikipedia.org/wiki/JSONP
— antyrat

6

se você estiver no apache, basta adicionar um arquivo .htaccess ao seu diretório com este conteúdo:

Header set Access-Control-Allow-Origin: *

Header set Access-Control-Allow-Headers: content-type

Header set Access-Control-Allow-Methods: *

5

No Ruby on Rails , você pode fazer em um controlador:

headers['Access-Control-Allow-Origin'] = '*'

em que controlador você coloca isso se for uma chamada ajax? Posso ver mais contexto de código?
— rigdonmr

5

Você pode fazê-lo funcionar sem modificar o servidor, fazendo com que o navegador inclua o cabeçalho Access-Control-Allow-Origin: *nas respostas das OPÇÕES HTTP.

No Chrome, use esta extensão . Se você estiver no Mozilla, verifique esta resposta .


5

Se você obtiver isso no Angular.js, não se esqueça do número da porta assim:

var Project = $resource(
    'http://localhost\\:5648/api/...', {'a':'b'}, {
        update: { method: 'PUT' }
    }
);

Veja aqui para mais informações.


4

Também temos o mesmo problema com o aplicativo phonegap testado no chrome. Uma máquina Windows que usamos abaixo do arquivo em lotes todos os dias antes de abrir o Chrome. Lembre-se, antes de executar isso, você precisa limpar todas as instâncias do chrome do gerenciador de tarefas ou pode selecionar o chrome para não executar em segundo plano.

LOTE: (use cmd)

cd D:\Program Files (x86)\Google\Chrome\Application\chrome.exe --disable-web-security

1

Na cidade Ruby Sinatra

response['Access-Control-Allow-Origin'] = '*' 

para todos ou

response['Access-Control-Allow-Origin'] = 'http://yourdomain.name' 

0

Quando você recebe a solicitação, pode

var origin = (req.headers.origin || "*");

do que quando você tem que responder, vá com algo assim:

res.writeHead(
    206,
    {
        'Access-Control-Allow-Credentials': true,
        'Access-Control-Allow-Origin': origin,
    }
);
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.