Estou desenvolvendo uma página que extrai imagens do Flickr e do Panoramio por meio do suporte AJAX do jQuery.
O lado do Flickr está funcionando bem, mas quando tento no $.get(url, callback)
Panoramio, vejo um erro no console do Chrome:
O XMLHttpRequest não pode carregar http://www.panoramio.com/wapi/data/get_photos?v=1&key=dummykey&tag=test&offset=0&length=20&callback=processImages&minx=-30&miny=0&maxx=0&maxy=150 . A origem nula não é permitida pelo Access-Control-Allow-Origin.
Se eu consultar esse URL diretamente de um navegador, ele funcionará bem. O que está acontecendo e posso contornar isso? Estou compondo minha consulta incorretamente ou isso é algo que o Panoramio faz para impedir o que estou tentando fazer?
O Google não encontrou nenhuma correspondência útil na mensagem de erro .
EDITAR
Aqui está um código de exemplo que mostra o problema:
$().ready(function () {
var url = 'http://www.panoramio.com/wapi/data/get_photos?v=1&key=dummykey&tag=test&offset=0&length=20&callback=processImages&minx=-30&miny=0&maxx=0&maxy=150';
$.get(url, function (jsonp) {
var processImages = function (data) {
alert('ok');
};
eval(jsonp);
});
});
Você pode executar o exemplo online .
EDIT 2
Agradeço a Darin por sua ajuda nisso. O CÓDIGO ACIMA ESTÁ ERRADO. Use isto:
$().ready(function () {
var url = 'http://www.panoramio.com/wapi/data/get_photos?v=1&key=dummykey&tag=test&offset=0&length=20&minx=-30&miny=0&maxx=0&maxy=150&callback=?';
$.get(url, function (data) {
// can use 'data' in here...
});
});
fonte
iframe
vocêdocument.write
, por exemplo?file:///C:/
). Nãoiframe
está envolvido.Respostas:
Para que conste, até onde sei, você teve dois problemas:
Você não estava passando um especificador de tipo "jsonp" para o seu
$.get
, portanto estava usando um XMLHttpRequest comum. No entanto, seu navegador oferece suporte ao CORS (compartilhamento de recursos de origem cruzada) para permitir XMLHttpRequest entre domínios, se o servidor o aceitar. Foi aí que oAccess-Control-Allow-Origin
cabeçalho entrou.Acredito que você tenha mencionado que estava executando a partir de um arquivo: // URL. Existem duas maneiras de os cabeçalhos do CORS sinalizarem que um XHR entre domínios está OK. Uma é enviar
Access-Control-Allow-Origin: *
(o que, se você estava acessando o Flickr via$.get
, eles deviam estar fazendo) enquanto a outra era ecoar o conteúdo doOrigin
cabeçalho. No entanto, osfile://
URLs produzem um nuloOrigin
que não pode ser autorizado por meio de eco-back.O primeiro foi resolvido de forma indireta pela sugestão de Darin
$.getJSON
. É um pouco mágico mudar o tipo de solicitação do padrão "json" para "jsonp" se ele vir a substringcallback=?
na URL.Isso resolveu o segundo ao não tentar mais executar uma solicitação CORS a partir de uma
file://
URL.Para esclarecer para outras pessoas, aqui estão as instruções simples para solução de problemas:
$.get
e definidodataType
comojsonp
.$.getJSON
e incluídocallback=?
no URL.http://
. Os scripts em execução viafile://
têm suporte limitado ao CORS.fonte
callback=?
não funcionou para mim, masjsonp=?
funcionou. Alguma explicação para isso?http://
? Ou existe uma maneira de simplesmente abrir o arquivo usando esse protocolo?Talvez você precise adicionar um HEADER no seu script chamado, aqui está o que eu tive que fazer no PHP:
Mais detalhes em Vários domínios AJAX ou serviços WEB (em francês).
fonte
Para um projeto HTML simples:
Em seguida, procure seu arquivo.
fonte
POST
solicitações que você recebe:code 501, message Unsupported method ('POST')
para os googles.Funciona para mim no Google Chrome v5.0.375.127 (recebo o alerta):
Também recomendo que você use o
$.getJSON()
método, pois o anterior não funciona no IE8 (pelo menos na minha máquina):Você pode experimentá-lo online a partir daqui .
ATUALIZAR:
Agora que você mostrou seu código, posso ver o problema. Você está tendo uma função anônima e uma função embutida, mas ambas serão chamadas
processImages
. É assim que o suporte a JSONP do jQuery funciona. Observe como estou definindo ocallback=?
para que você possa usar uma função anônima. Você pode ler mais sobre isso na documentação .Outra observação é que você não deve chamar eval. O parâmetro passado para sua função anônima já será analisado em JSON pelo jQuery.
fonte
?
, o JSON retornado será colocado entre parênteses. Você não define um parâmetro para sua função de retorno de chamada e o valor dethis
não parece ter um objeto de resposta (pelo menos, o.data
valor énull
).callback=?
indica ao jQuery para gerar internamente um nome de função aleatória, resultando em uma chamada para a função anônima que você passa.getJSON
. Estimado.Desde que o servidor solicitado suporte o formato de dados JSON, use a interface JSONP (JSON Padding). Ele permite que você faça solicitações de domínio externo sem servidores proxy ou itens de cabeçalho sofisticados.
fonte
É a mesma política de origem , é necessário usar uma interface JSON-P ou um proxy em execução no mesmo host.
fonte
Nós o gerenciamos através do
http.conf
arquivo (editado e, em seguida, reiniciado o serviço HTTP):No
Header set Access-Control-Allow-Origin "*"
, você pode colocar um URL preciso.fonte
Se você estiver testando localmente ou chamando o arquivo de algo parecido
file://
, precisará desativar a segurança do navegador.No MAC:
open -a Google\ Chrome --args --disable-web-security
fonte
No meu caso, o mesmo código funcionou bem no Firefox, mas não no Google Chrome. O console JavaScript do Google Chrome disse:
Eu tive que soltar a parte www do URL do Ajax para que ele correspondesse corretamente ao URL de origem e funcionou bem então.
fonte
Nem todos os servidores suportam jsonp. Exige que o servidor defina a função de retorno de chamada em seus resultados. Eu uso isso para obter respostas json de sites que retornam json puro, mas não suportam jsonp:
fonte
Eu uso o servidor Apache, então usei o módulo mod_proxy. Ativar módulos:
Adicione então:
Por fim, passe o proxy-url para o seu script.
fonte
Como nota final, a documentação do Mozilla diz explicitamente que
Como conseqüência, não é simplesmente uma prática ruim usar '*'. Simplesmente não funciona :)
fonte
Para PHP - este trabalho para mim no Chrome, safari e firefox
https://w3c.github.io/webappsec-cors-for-developers/#avoid-returning-access-control-allow-origin-null
usando axios chame php live services com file: //
fonte
header('Access-Control-Allow-Origin: '.( trim($_SERVER['HTTP_REFERER'],'/') ?:'null'),true);
permite a origem cruzada de um servidor remoto para outro e cai para (string) null para o arquivo local.Também recebi o mesmo erro no Chrome (não testei outros navegadores). Isso ocorreu porque eu estava navegando no domain.com em vez de www.domain.com. Um pouco estranho, mas eu poderia resolver o problema adicionando as seguintes linhas ao .htaccess. Ele redireciona domain.com para www.domain.com e o problema foi resolvido. Como sou um visitante preguiçoso, quase nunca digito o www, mas aparentemente em alguns casos é necessário.
fonte
Verifique se você está usando a versão mais recente do JQuery. Estávamos enfrentando esse erro no JQuery 1.10.2 e o erro foi resolvido após o uso do JQuery 1.11.1
fonte
Pessoal,
Eu tive um problema semelhante. Mas, usando o Fiddler, consegui entender o problema. O problema é que a URL do cliente configurada na implementação do CORS no lado da API da Web não deve ter uma barra final à direita. Depois de enviar sua solicitação pelo Google Chrome e inspecionar a guia TextView da seção Headers do Fiddler, a mensagem de erro informa algo como isto:
* "A origem da política especificada your_client_url: / 'é inválida. Não pode terminar com uma barra."
Isso é muito peculiar, porque funcionou sem problemas no Internet Explorer, mas me deu uma dor de cabeça ao testar usando o Google Chrome.
Eu removi a barra no código CORS e recompilei a API da Web, e agora a API está acessível via Chrome e Internet Explorer sem problemas. Por favor, dê uma chance.
Obrigado Andy
fonte
Há um pequeno problema na solução postada pelo CodeGroover acima , onde se você alterar um arquivo, terá que reiniciar o servidor para realmente usar o arquivo atualizado (pelo menos no meu caso).
Então, pesquisando um pouco, encontrei este Para usar:
E então ele servirá às
http://localhost:8000
.fonte