Làm cách nào để mở tệp đĩa cục bộ bằng JavaScript?


154

Tôi đã cố mở tập tin với

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

Trình duyệt không cho phép mở tệp cục bộ theo cách này, có thể vì lý do bảo mật. Tôi muốn sử dụng dữ liệu của tập tin ở phía máy khách. Làm cách nào tôi có thể đọc tệp cục bộ trong JavaScript?

Câu trả lời:


238

Đây là một ví dụ sử dụng 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>


Thông số kỹ thuật

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

Tính tương thích của trình duyệt web

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

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


1
Chỉ một giây, khi tôi tải lại cùng một tệp cuối cùng, nội dung sẽ không thay đổi (tôi nói về nội dung của nó, khi tôi chỉnh sửa văn bản tệp). Bạn có thể giúp?
Hydroper

1
@SamusHands Vâng, bạn nói đúng, tôi có thể tái tạo vấn đề trong Safari và Chrome (nó hoạt động tốt trong Firefox). Đặt giá trị của đầu vào cho nullmỗi onClicksự kiện sẽ thực hiện thủ thuật, xem: stackoverflow.com/a/12102992/63011
Paolo Moretti

3
Đây là một ví dụ tốt FileReader, nhưng một nhận xét displayContentsở trên: lưu ý rằng cài đặt innerHTMLnhư thế này với nội dung không đáng tin cậy có thể là một lỗ hổng bảo mật. (Để tự mình nhìn thấy điều này, hãy tạo một bad.txtcái gì đó giống như <img src="/nonexistent" onerror="alert(1);">và thấy rằng cảnh báo được thực thi, nó có thể là mã độc hơn.)
ShreevatsaR

2
@ShreevatsaR điểm thực sự tốt. Đoạn trích của tôi chỉ là một ví dụ, nhưng bạn nói đúng, nó không nên thúc đẩy các thói quen bảo mật xấu. Tôi thay thế innerHTMLbằng textContent. Cám ơn bạn đã góp ý.
Paolo Moretti

1
@TeylerHalama Bạn cũng có thể sử dụng DOMContentLoadedsự kiện này.
Paolo Moretti

59

Các cơ sở HTML5 FileReader không cho phép bạn xử lý tập tin địa phương, nhưng những PHẢI được lựa chọn bởi người sử dụng, bạn không thể đi rễ về đĩa người dùng tìm kiếm file.

Tôi hiện đang sử dụng tính năng này với các phiên bản phát triển của Chrome (6.x). Tôi không biết những trình duyệt khác hỗ trợ nó.


3
Phải, giờ đã có thể với HTML5. Nhìn vào đây
Flavien Volken

1
Quét nhanh thông số kỹ thuật được tham chiếu (cập nhật lần cuối 2012-07-12) cho thấy không có phương tiện để ghi tệp, chỉ đọc.
HBP

26

Bởi vì tôi không có cuộc sống và tôi muốn 4 điểm danh tiếng đó để tôi có thể thể hiện tình yêu của mình với (những người trả lời câu trả lời của) những người thực sự giỏi về mã hóa, tôi đã chia sẻ việc điều chỉnh mã của Paolo Moretti . Chỉ cần sử dụng openFile(chức năng để được thực hiện với nội dung tập tin là tham số đầu tiên) .

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>


2
Cảm ơn, rất hữu ích. Mặc dù lưu ý rằng thay vì mã mà bạn có clickElem(), thay vào đó bạn chỉ có thể gọi fileInput.click(). (ít nhất là trong phiên bản Chrome mới nhất)
Venryx 16/12/18

6

Thử

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

nhưng người dùng cần phải hành động để chọn tập tin


Tôi chỉ nhìn thấy Trình tin.innerText và lần đầu tiên tôi biết rằng một số phần tử được xác định bằng ID có thể được truy cập bằng ID làm tên biến hoặc thuộc tính của đối tượng cửa sổ.
fmalina

Vì vậy, câu trả lời là chúng ta không thể . html có vẻ rất hoàn hảo cho tương tác tài liệu! nhưng không phải mọi thứ đều có thể được phục vụ Một truy cập tệp cục bộ sẽ rất tốt
yota

@yota - trình duyệt buộc người dùng phải tương tác (và cảnh giác) có thể vì lý do bảo mật
Kamil Kiełczewski

-4

Phương thức yêu cầu xmlhttp không hợp lệ đối với các tệp trên đĩa cục bộ vì bảo mật trình duyệt không cho phép chúng tôi làm như vậy. Nhưng chúng tôi có thể ghi đè bảo mật trình duyệt bằng cách tạo một lối tắt-> nhấp chuột phải-> thuộc tính Trong mục tiêu "... trình duyệt location path.exe "append --allow-file-access-from-files. Điều này được kiểm tra trên chrome, tuy nhiên cần lưu ý rằng tất cả các cửa sổ trình duyệt phải được đóng và mã phải được chạy từ trình duyệt được mở thông qua phím tắt này.


-7

Bạn không thể. Các trình duyệt mới như Firefox, Safari, vv chặn giao thức 'tệp'. Nó sẽ chỉ hoạt động trên các trình duyệt cũ.

Bạn sẽ phải tải lên các tập tin bạn muốn.


-9

Javascript thường không thể truy cập các tệp cục bộ trong các trình duyệt mới nhưng đối tượng XMLHttpRequest có thể được sử dụng để đọc các tệp. Vì vậy, nó thực sự là Ajax (và không phải Javascript) đang đọc tệp.

Nếu bạn muốn đọc tệp abc.txt, bạn có thể viết mã dưới dạng:

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();

Bây giờ txtchứa nội dung của tệp abc.txt.


61
Ajax là JavaScript.
Người đàn ông Muffin

4
@TheMuffinMan và XML. (Không đồng bộ Javascript và XML)
Quintec

9
Câu trả lời này không liên quan vì op yêu cầu làm thế nào để mở các tệp nằm ở phía máy khách, không phải các tệp nằm trên máy chủ.
Thomas Nguyễn

4
@ThomasNguyen, câu hỏi này là kết quả google đầu tiên của "tập tin mở javascript" và dù sao câu trả lời này cũng có lợi.
Chuyến đi của Nathan

@ThomasNguyen Tôi đồng ý, nhưng một cách giải quyết có thể không có FileReader có thể là tải tệp lên máy chủ và đọc nó từ đó. Tôi vẫn đánh giá thấp câu trả lời này.
inf3rno
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.