Como abrir um arquivo de disco local com JavaScript?

155

Eu tentei abrir o arquivo com

window.open("file:///D:/Hello.txt");

O navegador não permite abrir um arquivo local dessa maneira, provavelmente por motivos de segurança. Eu quero usar os dados do arquivo no lado do cliente. Como posso ler o arquivo local em JavaScript?

Joval
fonte

Respostas:

238

Aqui está um exemplo usando FileReader:

function readSingleFile(e) {
  var file = e.target.files[0];
  if (!file) {
    return;
  }
  var reader = new FileReader();
  reader.onload = function(e) {
    var contents = e.target.result;
    displayContents(contents);
  };
  reader.readAsText(file);
}

function displayContents(contents) {
  var element = document.getElementById('file-content');
  element.textContent = contents;
}

document.getElementById('file-input')
  .addEventListener('change', readSingleFile, false);
<input type="file" id="file-input" />
<h3>Contents of the file:</h3>
<pre id="file-content"></pre>


Especificações

http://dev.w3.org/2006/webapi/FileAPI/

Compatibilidade do navegador

  • IE 10+
  • Firefox 3.6 ou superior
  • Chrome 13 ou superior
  • Safari 6.1 ou superior

http://caniuse.com/#feat=fileapi

Paolo Moretti
fonte
1
Apenas um segundo, quando recarrego o mesmo último arquivo, o conteúdo não muda (digo sobre o conteúdo, quando edito o texto do arquivo). Você pode ajudar?
Hydroper #
1
@SamusHands Sim, você está certo, posso reproduzir o problema no Safari e no Chrome (funciona bem no Firefox). Definir o valor da entrada para nullem cada onClickcaso deve fazer o truque, consulte: stackoverflow.com/a/12102992/63011
Paolo Moretti
3
Isso é bom como exemplo FileReader, mas um comentário ao displayContentsexposto acima: observe que configurações innerHTMLcomo essa com conteúdo não confiável podem ser uma vulnerabilidade de segurança. (Para ver isso por si mesmo, criar uma bad.txtcontendo algo como <img src="/nonexistent" onerror="alert(1);">e ver que o alerta é executado-lo poderia ser mais códigos maliciosos.)
ShreevatsaR
2
@ShreevatsaR realmente bom ponto. Meu snippet é apenas um exemplo, mas você está certo, não deve promover maus hábitos de segurança. Eu substituí innerHTMLpor textContent. Obrigado por seu comentário.
Paolo Moretti
1
@TeylerHalama Você também pode usar o DOMContentLoadedevento para isso.
Paolo Moretti
59

O recurso fileReader HTML5 permite que você processe arquivos locais, mas estes DEVEM ser selecionados pelo usuário, você não pode fazer root no disco do usuário procurando arquivos.

Atualmente, eu uso isso com versões de desenvolvimento do Chrome (6.x). Não sei o que outros navegadores suportam.

HBP
fonte
3
Certo, agora é possível com HTML5. Veja aqui
Flavien Volken
1
Uma verificação rápida da especificação referenciada (última atualização em 12/07/2012) não mostra nenhum recurso para gravação de arquivo, apenas leitura.
HBP
26

Como não tenho vida e quero esses quatro pontos de reputação, para mostrar meu amor (respostas positivas) por pessoas que são realmente boas em codificação, compartilhei minha adaptação do código de Paolo Moretti . Basta usar a openFile(função para ser executada com o conteúdo do arquivo como primeiro parâmetro) .

function dispFile(contents) {
  document.getElementById('contents').innerHTML=contents
}
function clickElem(elem) {
	// Thx user1601638 on Stack Overflow (6/6/2018 - /programming/13405129/javascript-create-and-save-file )
	var eventMouse = document.createEvent("MouseEvents")
	eventMouse.initMouseEvent("click", true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
	elem.dispatchEvent(eventMouse)
}
function openFile(func) {
	readFile = function(e) {
		var file = e.target.files[0];
		if (!file) {
			return;
		}
		var reader = new FileReader();
		reader.onload = function(e) {
			var contents = e.target.result;
			fileInput.func(contents)
			document.body.removeChild(fileInput)
		}
		reader.readAsText(file)
	}
	fileInput = document.createElement("input")
	fileInput.type='file'
	fileInput.style.display='none'
	fileInput.onchange=readFile
	fileInput.func=func
	document.body.appendChild(fileInput)
	clickElem(fileInput)
}
Click the button then choose a file to see its contents displayed below.
<button onclick="openFile(dispFile)">Open a file</button>
<pre id="contents"></pre>

SignatureSmileyfaceProductions
fonte
2
Obrigado, foi útil. Porém, observe que, em vez do código em que você está clickElem(), basta ligar fileInput.click(). (pelo menos na versão mais recente do Chrome)
Venryx
6

Experimentar

function readFile(file) {
  return new Promise((resolve, reject) => {
    let fr = new FileReader();
    fr.onload = x=> resolve(fr.result);
    fr.readAsText(file);
})}

mas o usuário precisa executar uma ação para escolher o arquivo

Kamil Kiełczewski
fonte
Acabei de ver o msg.innerText e, pela primeira vez, soube que alguns elementos identificados com IDs podem ser acessados ​​usando IDs como nomes de variáveis ​​ou propriedades do objeto de janela.
fmalina 26/02
então a resposta é que não podemos . html parece tão perfeito para interação de documentos! mas nem tudo pode ser servido. Um acesso local a arquivos teria sido bom
yota
@yota - o navegador força o usuário a interagir (e estar ciente) provavelmente por motivos de segurança
Kamil Kiełczewski
-4

O método de solicitação xmlhttp não é válido para os arquivos no disco local porque a segurança do navegador não nos permite fazê-lo. Mas podemos substituir a segurança do navegador criando um atalho-> clique com o botão direito do mouse-> propriedades no destino "... browser location path.exe "anexar - Permitir acesso ao arquivo a partir de arquivos.Este é testado no chrome, no entanto, deve-se tomar cuidado para que todas as janelas do navegador sejam fechadas e o código seja executado no navegador aberto por esse atalho.

user2450701
fonte
-7

Você não pode. Novos navegadores como Firefox, Safari etc. bloqueiam o protocolo 'arquivo'. Funcionará apenas em navegadores antigos.

Você precisará fazer o upload dos arquivos que deseja.

Youssef
fonte
-9

O Javascript normalmente não pode acessar arquivos locais em novos navegadores, mas o objeto XMLHttpRequest pode ser usado para ler arquivos. Portanto, na verdade, é o Ajax (e não o Javascript) que está lendo o arquivo.

Se você deseja ler o arquivo abc.txt, pode escrever o código como:

var txt = '';
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function(){
  if(xmlhttp.status == 200 && xmlhttp.readyState == 4){
    txt = xmlhttp.responseText;
  }
};
xmlhttp.open("GET","abc.txt",true);
xmlhttp.send();

Agora txtcontém o conteúdo do arquivo abc.txt.

Karanpreet Singh
fonte
61
Ajax é JavaScript.
O homem de muffin
4
@TheMuffinMan e XML. (Asynchronus Javascript e XML) #
1560 Quintec
9
Esta resposta não é relevante, pois o operador solicitou como abrir arquivos que residem no lado do cliente, não arquivos que residem no servidor.
Thomas Nguyen
4
@ThomasNguyen, esta pergunta é o primeiro resultado do google de "arquivo aberto javascript" e essa resposta é benéfica.
precisa
@ThomasNguyen Concordo, mas uma possível solução alternativa sem o FileReader pode ser carregar o arquivo no servidor e lê-lo a partir daí. Ainda assim, diminuí a votação desta resposta.
Inf3rno