Truy cập tệp cục bộ bằng JavaScript


177

Có thao tác tệp cục bộ nào được thực hiện với JavaScript không? Tôi đang tìm kiếm một giải pháp có thể được thực hiện mà không cần cài đặt như yêu cầu Adobe AIR .

Cụ thể, tôi muốn đọc nội dung từ một tệp và viết các nội dung đó sang tệp khác. Tại thời điểm này, tôi không lo lắng về việc có được quyền và tôi chỉ cho rằng tôi đã có đầy đủ quyền đối với các tệp này.


Câu trả lời:


87

Nếu người dùng chọn một tệp qua <input type="file">, bạn có thể đọcxử lý tệp đó bằng API tệp .

Thiết kế đọc hoặc ghi các tệp tùy ý không được phép theo thiết kế. Đó là một sự vi phạm của hộp cát. Từ Wikipedia -> Javascript -> Bảo mật :

JavaScript và DOM cung cấp tiềm năng cho các tác giả độc hại cung cấp các tập lệnh chạy trên máy khách thông qua web. Các tác giả trình duyệt chứa rủi ro này bằng cách sử dụng hai hạn chế. Đầu tiên, các tập lệnh chạy trong một hộp cát, trong đó chúng chỉ có thể thực hiện các hành động liên quan đến web, không phải các tác vụ lập trình có mục đích chung như tạo tệp .

CẬP NHẬT 2016 : Có thể truy cập trực tiếp vào hệ thống tệp thông qua API Hệ thống tệp , vốn chỉ được Chrome và Opera hỗ trợcuối cùng có thể không được các trình duyệt khác triển khai ( ngoại trừ Edge ). Để biết chi tiết, xem câu trả lời của Kevin .


28
Chỉ trích. Điều này là ngu ngốc, tất nhiên. Javascript được cho là một ngôn ngữ kịch bản không biết ứng dụng. Không phải mọi ứng dụng là một trình duyệt web. Tôi đến đây vì tôi thích kịch bản Photoshop chẳng hạn. Ngay cả khi một số ứng dụng không cung cấp các lớp truy cập tệp, việc chuẩn hóa chúng cho các ứng dụng đó phù hợp - một tính năng tiêu chuẩn nhưng tùy chọn, do đó, trải nghiệm từ một ứng dụng có thể chuyển được ngay cả khi không áp dụng phổ biến. Những gì tôi học được trong Photoshop sẽ không thể di chuyển được ngay cả với các máy chủ Javascript khác cho phép truy cập tệp.
Steve314

27
Javascript ngôn ngữ và làm bất cứ điều gì môi trường lưu trữ cho phép nó làm. SpiderMonkey có thể làm bất cứ điều gì mà bất kỳ ngôn ngữ nào khác có thể làm. Javascript trong Trình duyệt được sandbox.

35
Câu trả lời này có thể đã đúng 3 năm trước, nhưng chắc chắn nó không còn đúng nữa. Xem câu trả lời của @Horst Walter trên HTML5. Hoặc truy cập tại đây: html5rocks.com/en/tutorials/file/dndfiles
james.garriss

@ james.garriss Vâng, thực ra nó cũng không đúng ba năm trước. Trang này đã dạy tôi cách đọc / ghi với Firefox vào năm 2003 web.archive.org/web/20031229011919/http://www.captain.at/ ((bắt nạt cho XUL nhưng có sẵn trong trình duyệt với XpCom) và Microsoft đã có kịch bản lệnh shell javscript kiểu node.js vào những năm 1990 (và FileIO có sẵn trong trình duyệt với ActiveX)
original_username

Không thể thực hiện được nữa
SysDragon

158

Chỉ cần một bản cập nhật của các tính năng HTML5 là trong http://www.html5rocks.com/en/tutorials/file/dndfiles/ . Bài viết xuất sắc này sẽ giải thích chi tiết về quyền truy cập tệp cục bộ trong JavaScript. Tóm tắt từ bài viết được đề cập:

Đặc tả kỹ thuật cung cấp một số giao diện để truy cập các tệp từ hệ thống tệp 'cục bộ' :

  1. Tệp - một tệp riêng lẻ; cung cấp thông tin chỉ đọc như tên, kích thước tệp, loại MIME và tham chiếu đến phần xử lý tệp.
  2. FileList - một chuỗi giống như các đối tượng File. (Suy nghĩ <input type="file" multiple>hoặc kéo một thư mục tệp từ máy tính để bàn).
  3. Blob - Cho phép cắt một tệp thành các phạm vi byte.

Xem bình luận của Paul D. Waite bên dưới.


7
Đây không hẳn là một hệ thống tệp thực sự như những gì chúng ta đang sử dụng plugin Java hoặc Flash. Ví dụ: chúng tôi không thể liệt kê các tệp trên Bàn làm việc của người dùng trừ khi trước tiên anh ấy tự chọn chúng.
Pacerier

9
Có vẻ như các API này đang bị bỏ rơi: xem w3.org/TR/file-writer-apihtml5rocks.com/en/tutorials/file/filesystem
Paul D. Waite

4
Cẩn thận ở đó, đưa ra hình thức của W3C để lấy đi công nghệ hữu ích. Api hệ thống tập tin, chỉ được thực hiện trong chrome, sẽ không được chuyển tiếp. Các tập tin api, đã phổ biến hỗ trợ, được chấp nhận như là một dự thảo w3c làm việc và chúng tôi không còn có thể tưởng tượng cuộc sống mà không có nó. Tất nhiên chúng tôi vẫn đang ở trong một trình duyệt và chúng tôi phải đợi cho đến khi người dùng mang đến cho chúng tôi tệp, nhưng điều này giúp mở rộng đáng kể phạm vi của các ứng dụng web và sẽ không biến mất sớm.
bbsimonbb

21

CẬP NHẬT Tính năng này bị xóa kể từ Firefox 17 (xem https://ormszilla.mozilla.org/show_orms.cgi?id=546848 ).


Trên Firefox, bạn (lập trình viên) có thể thực hiện việc này từ trong tệp JavaScript:

netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserWrite");

và bạn (người dùng trình duyệt) sẽ được nhắc cho phép truy cập. (đối với Firefox bạn chỉ cần thực hiện việc này một lần mỗi khi trình duyệt khởi động)

Nếu người dùng trình duyệt là người khác, họ phải cấp quyền.


6
Điều này đưa ra một lỗi mà nó không được chấp nhận và bạn chỉ có thể thực hiện việc này trong một tiện ích mở rộng, không phải trang web javascript
Esailija

4
như liên kết này hiển thị, tính năng này đã bị xóa trong các phiên bản firefox sau này. support.mozilla.org/en-US/questions/944433
Makan Tayebi

3
oh, thật tệ Tôi nhận được bảo mật và tất cả những thứ đó, nhưng chúng tôi cần một cách cấp niềm tin để chạy các tệp javascript của riêng chúng tôi cục bộ.
Jason S

chắc chắn rồi. và tôi chưa tìm thấy cách nào khác để làm điều này.
Makan Tayebi

2
Vui lòng cập nhật câu trả lời để cho thấy rằng nó không được chấp nhận. Cảm ơn.
jpaugh

20

Như đã đề cập trước đó, API FileSystemFile , cùng với API FileWriter , có thể được sử dụng để đọc và ghi tệp từ ngữ cảnh của tab / cửa sổ trình duyệt đến máy khách.

Có một số điều liên quan đến API FileSystem và FileWriter mà bạn cần biết, một số trong số đó đã được đề cập, nhưng đáng để nhắc lại:

  • Việc triển khai API hiện chỉ tồn tại trong các trình duyệt dựa trên Chromium (Chrome & Opera)
  • Cả hai API đã được gỡ khỏi theo dõi tiêu chuẩn W3C vào ngày 24 tháng 4 năm 2014 và cho đến nay là độc quyền
  • Việc loại bỏ các API (hiện là độc quyền) khỏi các trình duyệt triển khai trong tương lai là một khả năng
  • Một hộp cát (một vị trí trên đĩa bên ngoài các tệp có thể không tạo hiệu ứng) được sử dụng để lưu trữ các tệp được tạo bằng API
  • Một hệ thống tệp ảo (cấu trúc thư mục không nhất thiết tồn tại trên đĩa ở dạng tương tự như khi truy cập từ trong trình duyệt) được sử dụng đại diện cho các tệp được tạo bằng API

Dưới đây là các ví dụ đơn giản về cách các API được sử dụng, trực tiếp và gián tiếp, song song để thực hiện những việc này:

Bánh nướng *

Viết tập tin:

bakedGoods.set({
    data: [{key: "testFile", value: "Hello world!", dataFormat: "text/plain"}],
    storageTypes: ["fileSystem"],
    options: {fileSystem:{storageType: Window.PERSISTENT}},
    complete: function(byStorageTypeStoredItemRangeDataObj, byStorageTypeErrorObj){}
});

Đọc tài liệu:

bakedGoods.get({
        data: ["testFile"],
        storageTypes: ["fileSystem"],
        options: {fileSystem:{storageType: Window.PERSISTENT}},
        complete: function(resultDataObj, byStorageTypeErrorObj){}
});

Sử dụng API tệp, FileWriter và FileSystem thô

Viết tập tin:

function onQuotaRequestSuccess(grantedQuota)
{

    function saveFile(directoryEntry)
    {

        function createFileWriter(fileEntry)
        {

            function write(fileWriter)
            {
                var dataBlob = new Blob(["Hello world!"], {type: "text/plain"});
                fileWriter.write(dataBlob);              
            }

            fileEntry.createWriter(write);
        }

        directoryEntry.getFile(
            "testFile", 
            {create: true, exclusive: true},
            createFileWriter
        );
    }

    requestFileSystem(Window.PERSISTENT, grantedQuota, saveFile);
}

var desiredQuota = 1024 * 1024 * 1024;
var quotaManagementObj = navigator.webkitPersistentStorage;
quotaManagementObj.requestQuota(desiredQuota, onQuotaRequestSuccess);

Đọc tài liệu:

function onQuotaRequestSuccess(grantedQuota)
{

    function getfile(directoryEntry)
    {

        function readFile(fileEntry)
        {

            function read(file)
            {
                var fileReader = new FileReader();

                fileReader.onload = function(){var fileData = fileReader.result};
                fileReader.readAsText(file);             
            }

            fileEntry.file(read);
        }

        directoryEntry.getFile(
            "testFile", 
            {create: false},
            readFile
        );
    }

    requestFileSystem(Window.PERSISTENT, grantedQuota, getFile);
}

var desiredQuota = 1024 * 1024 * 1024;
var quotaManagementObj = navigator.webkitPersistentStorage;
quotaManagementObj.requestQuota(desiredQuota, onQuotaRequestSuccess);

Mặc dù API FileSystem và FileWriter không còn trên đường chuẩn, nhưng theo tôi, việc sử dụng chúng có thể được biện minh trong một số trường hợp, bởi vì:

  • Sự quan tâm mới từ các nhà cung cấp trình duyệt không triển khai có thể đặt họ lại ngay trên đó
  • Tỷ lệ thâm nhập thị trường của các trình duyệt triển khai (dựa trên Chromium) cao
  • Google (người đóng góp chính cho Chromium) đã không đưa ra và ngày kết thúc cho các API

Tuy nhiên, "một số trường hợp" có bao gồm chính bạn hay không, là do bạn quyết định.

* Bakedoods được duy trì bởi không ai khác ngoài anh chàng này ngay tại đây :)


7

NW.js cho phép bạn tạo các ứng dụng máy tính để bàn bằng Javascript mà không cần tất cả các hạn chế bảo mật thường được đặt trên trình duyệt. Vì vậy, bạn có thể chạy các tệp thực thi với một chức năng, hoặc tạo / chỉnh sửa / đọc / ghi / xóa các tệp. Bạn có thể truy cập phần cứng, chẳng hạn như sử dụng CPU hiện tại hoặc tổng ram đang sử dụng, v.v.

Bạn có thể tạo một ứng dụng máy tính để bàn windows, linux hoặc mac mà không cần cài đặt.

Đây là một khung công tác cho NW.js, GUI phổ quát:


1
Cũng có thể truy cập các tệp cục bộ bằng Electron , một khung tương tự cho các ứng dụng máy tính để bàn JavaScript.
Anderson Green

6

Nếu bạn đang triển khai trên Windows, Windows Script Host cung cấp API JScript rất hữu ích cho hệ thống tệp và các tài nguyên cục bộ khác. Tuy nhiên, việc kết hợp các tập lệnh WSH vào một ứng dụng web cục bộ có thể không thanh lịch như bạn mong muốn.


3
Tôi muốn giải pháp độc lập với os (ít nhất là giữa windows và mac), vì vậy máy chủ script windows không thỏa mãn nó, trừ khi có một giải pháp tương đương cho nền tảng mac
Jared

5

Nếu bạn có trường nhập như

<input type="file" id="file" name="file" onchange="add(event)"/>

Bạn có thể nhận được nội dung tệp ở định dạng BLOB:

function add(event){
  var userFile = document.getElementById('file');
  userFile.src = URL.createObjectURL(event.target.files[0]);
  var data = userFile.src;
}

4

FSO.js kết thúc API HTML5 FileSystem mới đang được W3C chuẩn hóa và cung cấp một cách cực kỳ dễ dàng để đọc, ghi vào hoặc duyệt qua hệ thống tệp được hộp cát cục bộ. Nó không đồng bộ, vì vậy tệp I / O sẽ không can thiệp vào trải nghiệm người dùng. :)


1
FSO.js hiện không được IE, Mozilla hoặc Safari hỗ trợ.
Phillip Senn

2

Nếu bạn cần truy cập vào toàn bộ hệ thống tệp trên máy khách, đọc / ghi tệp, xem các thư mục để thay đổi, khởi động ứng dụng, mã hóa hoặc ký tài liệu, v.v. hãy xem JSFS.

Nó cho phép truy cập an toàn và không giới hạn từ trang web của bạn đến tài nguyên máy tính trên máy khách mà không cần sử dụng công nghệ plugin trình duyệt như AcitveX hoặc Java Applet. Tuy nhiên, một phần mềm cũng phải được cài đặt.

Để làm việc với JSFS, bạn cần có kiến ​​thức cơ bản về phát triển Java và Java EE (Servlets).

Vui lòng tìm thấy JSFS tại đây: https://github.com/jsfsproject/jsfs . Nó miễn phí và được cấp phép theo GPL


1

Giả sử rằng bất kỳ tệp nào mà mã JavaScript có thể cần, phải được người dùng cho phép trực tiếp. Người tạo các trình duyệt nổi tiếng không cho phép JavaScript truy cập các tệp nói chung.

Ý tưởng chính của giải pháp là: mã JavaScript không thể truy cập tệp bằng cách có URL cục bộ. Nhưng nó có thể sử dụng tệp bằng cách có DataURL: vì vậy nếu người dùng duyệt tệp và mở tệp, JavaScript sẽ lấy "DataURL" trực tiếp từ HTML thay vì lấy "URL".

Sau đó, nó biến DataURL thành một tệp, sử dụng hàm readAsDataURL và đối tượng FileReader. Nguồn và một hướng dẫn đầy đủ hơn với một ví dụ hay là trong:

https://developer.mozilla.org/en-US/docs/Web/API/FileReader?redirectlocale=en-US&redirectslug=DOM%2FFileReader


0

Có một sản phẩm (thương mại), "localFS" có thể được sử dụng để đọc và ghi toàn bộ hệ thống tệp trên máy khách.

Ứng dụng Windows nhỏ phải được cài đặt và tệp .js nhỏ có trong trang của bạn.

Là một tính năng bảo mật, quyền truy cập hệ thống tệp có thể được giới hạn trong một thư mục và được bảo vệ bằng khóa bí mật.

https://www.fathsoft.com/localfs


-4

nếu bạn đang sử dụng angularjs & aspnet / mvc, để truy xuất các tệp json, bạn phải cho phép loại mime tại cấu hình web

<staticContent>
    <remove fileExtension=".json" />
    <mimeMap fileExtension=".json" mimeType="application/json" />
  </staticContent>
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.