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

184

Eu criei um pequeno arquivo xslt para criar uma saída html chamada weather.xsl com o código da seguinte maneira:

<!-- DWXMLSource="http://weather.yahooapis.com/forecastrss?w=38325&u=c" -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
exclude-result-prefixes="yweather"
xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/">
    <img src="{/*/*/item/yweather:condition/@text}.jpg"/>
</xsl:template>
</xsl:stylesheet>

Eu quero carregar a saída html em uma div em um arquivo html que estou tentando fazer usando o jQuery da seguinte maneira:

<div id="result">
<script type="text/javascript">
$('#result').load('weather.xsl');
</script>
</div>

Mas estou recebendo o seguinte erro: Origem nula não é permitida pelo Access-Control-Allow-Origin.

Eu li sobre a adição de um cabeçalho ao xslt, mas não tenho certeza de como fazer isso; portanto, qualquer ajuda seria apreciada e, se o carregamento na saída html não puder ser feito dessa maneira, aconselhamento sobre outras formas fazer isso seria ótimo.

dudledok
fonte
Essa é a sua ligação real load ? Não existe nenhum caminho?
TJ Crowder

Respostas:

227

Origin nullé o sistema de arquivos local, o que sugere que você esteja carregando a página HTML que faz a loadchamada por meio de uma file:///URL (por exemplo, basta clicar duas vezes nela em um navegador de arquivos local ou similar). Navegadores diferentes adotam abordagens diferentes para aplicar a Política de mesma origem a arquivos locais.

Meu palpite é que você está vendo isso usando o Chrome. As regras do Chrome para aplicar o SOP aos arquivos locais são muito rígidas, não permitindo o carregamento de arquivos do mesmo diretório que o documento. O Opera também. Alguns outros navegadores, como o Firefox, permitem acesso limitado aos arquivos locais. Mas, basicamente, o uso do ajax com recursos locais não funcionará em vários navegadores.

Se você está apenas testando algo localmente que realmente implantará na Web, em vez de usar arquivos locais, instale um servidor Web simples e teste através de http://URLs. Isso fornece uma imagem de segurança muito mais precisa.

TJ Crowder
fonte
1
Após o upload, não recebo mais o Origin nulo, mas continuo recebendo "não permitido pelo Access-Control-Allow-Origin".
dudledok
3
Se o recurso que você está carregando for o que você mostrou ( $('#result').load('weather.xsl');), isso não deve acontecer, porque a solicitação está claramente na mesma origem. Se você está tentando carregar de algum outro lugar (por exemplo, $('#result').load('http://somewhere.else/weather.xsl');), está executando o SOP novamente, mas de uma maneira diferente. As solicitações Ajax são restritas à mesma origem (consulte o link na resposta) ou, se você estiver usando um navegador habilitado para CORS e o servidor suportar CORs, o servidor poderá escolher se deseja permitir a solicitação entre origens.
TJ Crowder
Eu mudei o URL de carregamento. Mudar de volta para a pergunta faz com que ela carregue bem. Obrigado pela ajuda
dudledok
2
Qual é a maneira mais rápida e simples de configurar um servidor Web simples? O IIS seria a maneira mais simples aqui?
Ciaran Gallagher
13
@CiaranG Corri python -m SimpleHTTPServerde uma linha de comando e fui para o localhost: 8000, trabalhou para mim. O Python vem pré-instalado com o Mac OS X; pode ser necessário instalar se estiver usando outro sistema operacional.
26613 Dave Liepmann
216

Chrome e Safari tem uma restrição no uso de ajax com recursos locais. É por isso que está lançando um erro como

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

Solução: use o Firefox ou faça o upload de seus dados para um servidor temporário. Se você ainda deseja usar o Chrome, inicie-o com a opção abaixo;

--allow-file-access-from-files

Mais informações sobre como adicionar o parâmetro acima ao seu Chrome: Clique com o botão direito do mouse no ícone do Chrome na barra de tarefas, clique com o botão direito do mouse no Google Chrome na janela pop-up e clique em Propriedades e adicione o parâmetro acima na caixa de texto Destino na guia Atalho. Vai gostar como abaixo;

C:\Users\XXX_USER\AppData\Local\Google\Chrome\Application\chrome.exe --allow-file-access-from-files

Espero que isso ajude!

Gokhan Tank
fonte
19
No Mac OS X, você pode iniciar o Chrome com esta opção abrindo um terminal e digitando: /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --allow-file-access-from-files & Observe o final & é apenas para continuar usando o Terminal e não é necessário. NOTA: Se você fechar o terminal, ele fechará a janela do Chrome.
Bruno Bernardino
3
Fiz tudo isso e fechou e abriu. ainda não vai (Chrome 27.0.1453.116 m no XP)
mplungjan 25/06
Eu não estou sendo capaz de adicionar este parâmetro no Windows 8 ..., quem sabe como fazê-lo ...?
Morty
Eu estou correndo de um servidor web. Que diabos? Como posso descobrir onde ele está carregando arquivos locais?
Andy
Quando tento adicionar o arquivo --allow-access-from-files ao caminho de destino, recebo uma mensagem ".... inválida", a solução htis ainda é válida?
alex
48

Só queria acrescentar que a resposta "execute um servidor da web" parece bastante assustadora, mas se você tem python no seu sistema (instalado por padrão pelo menos no MacOS e em qualquer distribuição Linux), é tão fácil quanto:

python -m http.server  # with python3

ou

python -m SimpleHTTPServer  # with python2

Portanto, se você tiver seu arquivo html myfile.htmlem uma pasta, digamos mydir, tudo o que você precisa fazer é:

cd /path/to/mydir
python -m http.server  # or the python2 alternative above

Em seguida, aponte seu navegador para:

http://localhost:8000/myfile.html

E você está pronto! Funciona em todos os navegadores , sem desativar a segurança da web, permitir arquivos locais ou até mesmo reiniciar o navegador com opções de linha de comando.

gozzilli
fonte
2
python 3 equivalentes no Windows é: python -m http.server [<portno>]
Aragorn
Python 3: python3 -m http.server
João Nunes
Python 2 no Linux, escolhendo a porta 8080 (ou qualquer outra que você quiser):python -m SimpleHTTPServer 8080
Rodrigo
2

Gostaria de acrescentar humildemente que, de acordo com esta fonte do SO: https://stackoverflow.com/a/14671362/1743693 , esse tipo de problema agora está parcialmente resolvido simplesmente usando a seguinte instrução jQuery:

<script> 
    $.support.cors = true;
</script>

Eu tentei no IE10.0.9200 e funcionou imediatamente (usando o jquery-1.9.0.js).

No chrome 28.0.1500.95 - esta instrução não funciona (isso acontece todo como David reclama nos comentários no link acima)

A execução do chrome com --allow-file-access-from-files não funcionou para mim (como as reivindicações de Maistora acima)

Orberkov
fonte
2

Adicionando um pouco para usar a solução de Gokhan para usar:

--allow-file-access-from-files

Agora você só precisa acrescentar o texto acima no texto de destino, seguido de um espaço. feche todas as instâncias do navegador chrome após adicionar a propriedade acima. Agora reinicie o chrome pelo ícone em que você adicionou esta propriedade. Deve funcionar para todos.

saurabh
fonte
O parâmetro já foi apresentado pelo Ghokan Tank e descobrir como sempre fazer o navegador iniciar com esse parâmetro não faz parte da questão. Além disso, você não pode assumir que todos usam o Microsoft Windows.
Jnns #
0

Eu estava procurando uma solução para fazer uma solicitação XHR para um servidor a partir de um arquivo html local e encontrei uma solução usando o Chrome e o PHP. (sem Jquery)

Javascripts:

var x = new XMLHttpRequest(); 
if(x) x.onreadystatechange=function(){ 
    if (x.readyState === 4 && x.status===200){
        console.log(x.responseText); //Success
    }else{ 
        console.log(x); //Failed
    }
};
x.open(GET, 'http://example.com/', true);
x.withCredentials = true;
x.send();

O cabeçalho de solicitação do meu Chrome Origin: null

Meu cabeçalho de resposta do PHP (observe que 'null' é uma string ). HTTP_REFERER permite origem cruzada de um servidor remoto para outro.

header('Access-Control-Allow-Origin: '.(trim($_SERVER['HTTP_REFERER'],'/')?:'null'),true);
header('Access-Control-Allow-Credentials:true',true);

Consegui conectar com sucesso ao meu servidor. Você pode desconsiderar os cabeçalhos de credenciais, mas isso funciona para mim com o Apache AuthType Basicativado

Eu testei a compatibilidade com FF e Opera, funciona em muitos casos, como:

De um IP da LAN da VM (192.168.0.x) de volta para o IP (público) da WAN da VM: porta
De um IP da LAN da VM de volta para um nome de domínio do servidor remoto.
De um arquivo .HTML local para o IP da LAN da VM e / ou IP da WAN da VM: porta,
De um arquivo .HTML local para um nome de domínio do servidor remoto.
E assim por diante.

Louis Loudog Trottier
fonte
0

Você pode carregar um arquivo Javascript local (na árvore abaixo da file:/página de origem) usando a tag source:

<script src="my_data.js"></script>

Se você codificar sua entrada em Javascript, como neste caso:

mydata.js :

$xsl_text = "<xsl:stylesheet version="1.0" + ....

(isso é mais fácil para json), você terá seus 'dados' em uma variável global Javascript para usar como desejar.

Rico
fonte