XMLHttpRequest A origem nula não é permitida Access-Control-Allow-Origin para o arquivo: /// to file: /// (Serverless)

209

Estou tentando criar um site que pode ser baixado e executado localmente, iniciando seu arquivo de índice.

Todos os arquivos são locais, nenhum recurso é usado online.

Quando tento usar o plug-in AJAXSLT para o jQuery para processar um arquivo XML com um modelo XSL (em subdiretórios), recebo os seguintes erros:

XMLHttpRequest cannot load file:///C:/path/to/XSL%20Website/data/home.xml. Origin null is not allowed by Access-Control-Allow-Origin.

XMLHttpRequest cannot load file:///C:/path/to/XSL%20Website/assets/xsl/main.xsl. Origin null is not allowed by Access-Control-Allow-Origin.

O arquivo de índice que faz a solicitação é file:///C:/path/to/XSL%20Website/index.htmlenquanto os arquivos JavaScript usados ​​estão armazenados file:///C:/path/to/XSL%20Website/assets/js/.

Como posso fazer para corrigir esse problema?

Kevin Herrera
fonte

Respostas:

177

Nos casos em que a execução de um servidor da web local não é uma opção, você pode permitir o acesso do Chrome aos file://arquivos por meio de uma opção de navegador. Após algumas pesquisas, encontrei essa discussão , que menciona uma opção de navegador na postagem de abertura. Execute sua instância do Chrome com:

chrome.exe --allow-file-access-from-files

Isso pode ser aceitável para ambientes de desenvolvimento, mas pouco mais. Você certamente não quer isso o tempo todo. Ainda parece ser um problema em aberto (a partir de janeiro de 2011).

Consulte também: Problemas com o jQuery getJSON usando arquivos locais no Chrome

Courtney Christensen
fonte
1
@ Rich, feliz que ajudou! Gostaria de saber se haverá uma demanda maior por isso, com o esforço do Google em relação a aplicativos baseados em navegador. Eu acho que a demanda só vai crescer.
Courtney Christensen
4
isso foi útil para o Mac OS X cweagans.net/blog/2011/1/24/…
kinet
1
Obrigado, eu queria saber onde eu codifiquei errado, parece que o navegador é o problema.
Arda #
4
Existe algum motivo - permitir o acesso a arquivos de arquivos não resolveria o problema. Estou simplesmente tentando carregar um arquivo de script como $ .getScript ("application.js"); e obtenha o erro descrito na pergunta.
Denzo
1
Isso funciona, no entanto "Antes de executar o comando, verifique se toda a sua janela do Chrome está fechada e não está em execução. Ou, o parâmetro da linha de comando não seria eficaz." Chrome.exe --allow-file-access-from- arquivos "" ( stackoverflow.com/a/4208455/1272428 )
rluks
87

Essencialmente, a única maneira de lidar com isso é ter um servidor da Web em execução no host local e atendê-los a partir daí.

Não é seguro para um navegador permitir que uma solicitação ajax acesse qualquer arquivo no seu computador; portanto, a maioria dos navegadores parece tratar solicitações "file: //" como não tendo origem para os fins da " mesma política de origem "

Iniciar um servidor da Web pode ser tão trivial quanto cdentrar no diretório em que os arquivos estão:

python -m SimpleHTTPServer
Singletoned
fonte
1
Espero desenvolver uma solução que não exija que o usuário use nada além do navegador da web. O uso de Python, qualquer intérprete ou qualquer software independente de sistema não é viável.
Kevin Herrera
5
Bem, a única outra solução em que posso pensar é carregar a coisa inteira em uma única página, para que você não precise fazer solicitações de ajax ao sistema de arquivos.
Singletoned
2
Obrigado @Singletoned! Estou usando sua solução e é muito útil!
Hendy Irawan
4
E se você estiver usando Python 3, o comando seria python -m http.server.
alextercete
4

Aqui está um AppleScript que iniciará o Chrome com a opção - Permitir acesso a arquivos a partir de arquivos ativada, para os desenvolvedores do OSX / Chrome por aí:

set chromePath to POSIX path of "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"    
set switch to " --allow-file-access-from-files"
do shell script (quoted form of chromePath) & switch & " > /dev/null 2>&1 &"
ericsoco
fonte
14
Você pode apenas usar open (1) para adicionar as bandeiras: open -a 'Google Chrome' --args --allow-file-access-from-files.
21711 Josh Lee
4

Esta solução permitirá que você carregue um script local usando jQuery.getScript (). Essa é uma configuração global, mas você também pode definir a opção crossDomain por solicitação.

$.ajaxPrefilter( "json script", function( options ) {
  options.crossDomain = true;
});
Renaud
fonte
funcionou como um encanto para carregar um arquivo js local a partir de um arquivo html local! obrigado, exatamente o que eu precisava.
user1577390
4

Que tal usar a função javascript FileReader para abrir o arquivo local, ou seja:

<input type="file" name="filename" id="filename">
<script>
$("#filename").change(function (e) {
  if (e.target.files != undefined) {
    var reader = new FileReader();
    reader.onload = function (e) {
        // Get all the contents in the file
        var data = e.target.result; 
        // other stuffss................            
    };
    reader.readAsText(e.target.files.item(0));
  }
});
</script>

Agora clique no Choose filebotão e navegue até o arquivofile:///C:/path/to/XSL%20Website/data/home.xml

suhailvs
fonte
3

Inicie o chrome assim para ignorar esta restrição: open -a "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --args --allow-file-access-from-files .

Derivado do comentário de Josh Lee, mas eu precisava especificar o caminho completo para o Google Chrome para evitar que o Google Chrome fosse aberto na minha partição do Windows (no Parallels).

Stunner
fonte
2

A maneira como acabei de solucionar isso não é usar o XMLHTTPRequest, mas incluir os dados necessários em um arquivo javascript separado. (No meu caso, eu precisava de um blob SQLite binário para usar com https://github.com/kripken/sql.js/ )

Criei um arquivo chamado base64_data.js(e useibtoa() para converter os dados necessários e inseri-los em<div> para poder copiá-los).

var base64_data = "U1FMaXRlIGZvcm1hdCAzAAQA ...<snip lots of data> AhEHwA==";

e incluiu os dados no html como javascript normal:

<div id="test"></div>

<script src="base64_data.js"></script>
<script>
    data = atob(base64_data);
    var sqldb = new SQL.Database(data);
    // Database test code from the sql.js project
    var test = sqldb.exec("SELECT * FROM Genre");
    document.getElementById("test").textContent = JSON.stringify(test);
</script>

Eu imagino que seria trivial modificar isso para ler JSON, talvez até XML; Vou deixar isso como um exercício para o leitor;)

Anthony Briggs
fonte
1

Você pode tentar colocar 'Access-Control-Allow-Origin':'*'em response.writeHead(, {[here]}).

Shikon
fonte
6
de onde vem o response.writeHead, como o chamo e de onde? Você pode dar mais exemplos? Lembre-se de que este é um sistema de arquivos local, não um servidor. Meu entendimento é que o valor só pode ser definido em um servidor?
Joseph Astrahan
0

use o 'servidor da web para o aplicativo Chrome'. (você realmente o possui no seu PC, quer você saiba ou não. basta pesquisar em cortana!). abra-o e clique em 'escolher arquivo' escolha a pasta com o seu arquivo. na verdade, não selecione seu arquivo. selecione sua pasta de arquivos e clique no (s) link (s) no botão 'escolher pasta'.

se não o levar ao arquivo, adicione o nome do arquivo aos urs. como isso:

   https://127.0.0.1:8887/fileName.txt

link para o servidor web para chrome: clique em mim

pessoa humana
fonte