¿Cómo abrir un archivo de disco local con JavaScript?

155

Traté de abrir el archivo con

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

El navegador no permite abrir un archivo local de esta manera, probablemente por razones de seguridad. Quiero usar los datos del archivo en el lado del cliente. ¿Cómo puedo leer el archivo local en JavaScript?

Joval
fuente

Respuestas:

238

Aquí hay un ejemplo 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>


Especificaciones

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

Compatibilidad del navegador

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

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

Paolo Moretti
fuente
1
Solo un segundo, cuando vuelvo a cargar el mismo último archivo, el contenido no cambia (digo sobre su contenido, cuando edito el texto del archivo). ¿Puede usted ayudar?
Hydroper
1
@SamusHands Sí, tienes razón, puedo reproducir el problema en Safari y Chrome (funciona bien en Firefox). Establecer el valor de la entrada nullen cada onClickevento debería ser el truco, consulte: stackoverflow.com/a/12102992/63011
Paolo Moretti
3
Esto es bueno como un ejemplo FileReader, pero un comentario sobre lo displayContentsanterior: tenga en cuenta que una configuración innerHTMLcomo esta con contenido no confiable puede ser una vulnerabilidad de seguridad. (Para verlo usted mismo, cree un elemento que bad.txtcontenga algo así <img src="/nonexistent" onerror="alert(1);">y vea que la alerta se ejecuta, podría ser un código más malicioso)
ShreevatsaR
2
@ShreevatsaR realmente buen punto. Mi fragmento es solo un ejemplo, pero tienes razón, no debería promover malos hábitos de seguridad. Reemplacé innerHTMLcon textContent. Gracias por tu comentario.
Paolo Moretti
1
@TeylerHalama También puedes usar el DOMContentLoadedevento para eso.
Paolo Moretti
59

El recurso HTML5 fileReader le permite procesar archivos locales, pero estos DEBEN ser seleccionados por el usuario, no puede enraizar sobre el disco de los usuarios en busca de archivos.

Actualmente lo uso con versiones de desarrollo de Chrome (6.x). No sé qué otros navegadores lo admiten.

HBP
fuente
3
Bien, ahora es posible con HTML5. Mira aquí
Flavien Volken
1
Un escaneo rápido de la especificación referenciada (última actualización 2012-07-12) no muestra facilidades para la escritura de archivos, solo lectura.
HBP
26

Debido a que no tengo vida y quiero esos 4 puntos de reputación para poder mostrar mi amor a las personas que realmente son buenas para codificar, he compartido mi adaptación del código de Paolo Moretti . Simplemente use la openFile(función para ejecutarse con el contenido del archivo como primer 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
fuente
2
Gracias, fue útil. Aunque tenga en cuenta que en lugar de ese código que tiene clickElem(), puede simplemente llamar fileInput.click(). (al menos en la última versión de Chrome)
Venryx
6

Tratar

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

pero el usuario debe tomar medidas para elegir el archivo

Kamil Kiełczewski
fuente
Acabo de ver msg.innerText y por primera vez aprendí que se puede acceder a algunos elementos identificados con ID utilizando ID como nombres de variables o propiedades del objeto de ventana.
fmalina
entonces la respuesta es que no podemos . ¡HTML parece tan perfecto para la interacción de documentos! pero no todo se puede servir. Un acceso a archivos locales hubiera sido bueno
yota
@yota - el navegador obliga al usuario a interactuar (y estar atento) probablemente por razones de seguridad
Kamil Kiełczewski
-4

El método de solicitud xmlhttp no es válido para los archivos en el disco local porque la seguridad del navegador no nos permite hacerlo. Pero podemos anular la seguridad del navegador creando un acceso directo-> clic derecho-> propiedades en destino "... navegador location path.exe "adjunte --allow-file-access-from-files. Esto se prueba en Chrome, sin embargo, se debe tener cuidado de que todas las ventanas del navegador se cierren y el código se ejecute desde el navegador abierto a través de este acceso directo.

usuario2450701
fuente
-7

No puedes Los nuevos navegadores como Firefox, Safari, etc. bloquean el protocolo 'archivo'. Solo funcionará en navegadores antiguos.

Tendrás que subir los archivos que quieras.

Youssef
fuente
-9

Por lo general, Javascript no puede acceder a archivos locales en nuevos navegadores, pero el objeto XMLHttpRequest se puede usar para leer archivos. Entonces, en realidad, es Ajax (y no Javascript) el que está leyendo el archivo.

Si desea leer el archivo abc.txt, puede escribir el 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();

Ahora txtcontiene el contenido del archivo abc.txt.

Karanpreet Singh
fuente
61
Ajax es JavaScript.
The Muffin Man
44
@TheMuffinMan y XML. (Asynchronus Javascript y XML)
Quintec
9
Esta respuesta no es relevante ya que el operador solicitó cómo abrir archivos que residen en el lado del cliente, no archivos que residen en el servidor.
Thomas Nguyen
44
@ThomasNguyen, esta pregunta es el primer resultado de Google de "javascript open file" y esta respuesta es beneficiosa.
Nathan Goings
@ThomasNguyen Estoy de acuerdo, pero una posible solución sin FileReader podría ser subir el archivo al servidor y leerlo desde allí. Aún así, rechacé esta respuesta.
inf3rno