Читання вмісту файлів на стороні клієнта у javascript у різних браузерах


113

Я намагаюся надати лише сценарій для читання вмісту файлу на клієнтській машині через браузер.

У мене є рішення, яке працює з Firefox та Internet Explorer. Це не дуже, але на даний момент я пробую тільки:

function getFileContents() {
    var fileForUpload = document.forms[0].fileForUpload;
    var fileName = fileForUpload.value;

    if (fileForUpload.files) {
        var fileContents = fileForUpload.files.item(0).getAsBinary();
        document.forms[0].fileContents.innerHTML = fileContents;
    } else {
        // try the IE method
        var fileContents = ieReadFile(fileName);
        document.forms[0].fileContents.innerHTML = fileContents;
    }
}       

function ieReadFile(filename) 
{
    try
    {
        var fso  = new ActiveXObject("Scripting.FileSystemObject"); 
        var fh = fso.OpenTextFile(filename, 1); 
        var contents = fh.ReadAll(); 
        fh.Close();
        return contents;
    }
    catch (Exception)
    {
        return "Cannot open file :(";
    }
}

Я можу зателефонувати, getFileContents()і він запише вміст у fileContentsтекстову область.

Чи є спосіб це зробити в інших браузерах?

На даний момент мене найбільше хвилює Safari та Chrome, але я відкритий для пропозицій щодо будь-якого іншого браузера.

Редагувати: У відповідь на запитання "Чому ти хочеш це робити?":

В основному, я хочу хеш-вміст файлу разом із одноразовим паролем на стороні клієнта, щоб я міг надіслати цю інформацію назад як підтвердження.


не те, що у мене є відповідь, а просто для наочності, чи потрібно вам знати розташування файлу? Якщо ні, то чи слід розташувати файл зчитуватися з файлового вводу чи це може бути текстове поле / текстовий пояс / будь-що інше?
Darko Z

Гарне питання. Ні, мене не дуже цікавить, звідки береться файл, лише його вміст. Використання введення файлів здається мені розумним, хоча як це рідний html - є ще одна менша річ, яку я повинен зробити.
Дамовіса

чому ти взагалі хочеш це робити? сервер призначений для цього.
geowa4

Гаразд, коротше: користувач вводить пароль і вибирає файл. Пароль перемішується з вмістом файлу, і він надсилається на сервер разом із файлом. Коли він потрапить туди, я можу перевірити, чи був використаний правильний пароль клієнта.
Дамовіса

Відповіді:


159

Відредаговано, щоб додати інформацію про файловий API

Оскільки я спочатку писав цю відповідь, API файлів був запропонований як стандартний і реалізований у більшості браузерів (станом на IE 10, який додав підтримку FileReaderAPI, описаного тут, хоча ще не FileAPI). API трохи складніше, ніж старший API Mozilla, оскільки він розроблений для підтримки асинхронного читання файлів, кращої підтримки бінарних файлів та декодування різних текстових кодувань. У Мережі розробників Mozilla є деяка документація , а також різні приклади в Інтернеті. Ви використовуєте його наступним чином:

var file = document.getElementById("fileForUpload").files[0];
if (file) {
    var reader = new FileReader();
    reader.readAsText(file, "UTF-8");
    reader.onload = function (evt) {
        document.getElementById("fileContents").innerHTML = evt.target.result;
    }
    reader.onerror = function (evt) {
        document.getElementById("fileContents").innerHTML = "error reading file";
    }
}

Оригінальна відповідь

Здається, це не існує в WebKit (таким чином, Safari та Chrome). Тільки ключі , що файл об'єкт має є fileNameі fileSize. Відповідно до повідомлення фіксації для підтримки файлу File and FileList, вони надихаються об'єктом File Mozilla , але, здається, вони підтримують лише підмножину функцій.

Якщо ви хочете змінити це, ви завжди можете надіслати виправлення до проекту WebKit. Іншою можливістю було б запропонувати API Mozilla для включення в HTML 5 ; WHATWG список розсилки, ймовірно, краще місце , щоб зробити це. Якщо ви це зробите, то набагато ймовірніше, що буде існувати крос-браузерний спосіб зробити це, принаймні, через пару років. Звичайно, подання виправлення або пропозиція щодо включення до HTML 5 означає певну роботу, яка захищає ідею, але той факт, що Firefox вже реалізує її, дає вам щось із початку.


Дякую за це - я не думаю, що я достатньо присвячений цьому моменту, щоб подати виправлення. Це те, що ви, мабуть, не хотіли б все-таки відбуватися без вашого відома. Це щось зламає
пісочну скриньку

4
Це не порушує пісочну скриньку браузера, оскільки ви навмисно вибрали для завантаження цей файл; якщо він може потрапити на сервер, він може повернутися до браузера, просто за додаткову поїздку. З огляду на роботу, яка перетворюється в режим офлайн-роботи для веб-додатків, це буде розумною особливістю.
Брайан Кемпбелл

Гм, насправді це справедливо. Для вибору цього файлу була взаємодія користувача. Дякую.
Дамовіса

@Damovisa Я не знаю, чи все-таки вам це все одно, але я подумав, що я оновлю свою відповідь, щоб згадати про новий файловий API, який робить те, що ви шукаєте, і реалізований у Firefox, Chrome та щомісячних версіях Сафарі.
Брайан Кемпбелл

Дивовижне, дякую за це. Я перейшов до іншої роботи, але добре знати, що відповідь є :)
Дамовіса

25

Для того, щоб прочитати вибраний користувачем файл, за допомогою діалогового вікна відкриття файлу ви можете використовувати <input type="file">тег. Інформацію про неї можна знайти у MSDN . Коли файл обраний, ви можете використовувати API FileReader для читання вмісту.

function onFileLoad(elementId, event) {
    document.getElementById(elementId).innerText = event.target.result;
}

function onChooseFile(event, onLoadFileHandler) {
    if (typeof window.FileReader !== 'function')
        throw ("The file API isn't supported on this browser.");
    let input = event.target;
    if (!input)
        throw ("The browser does not properly implement the event object");
    if (!input.files)
        throw ("This browser does not support the `files` property of the file input.");
    if (!input.files[0])
        return undefined;
    let file = input.files[0];
    let fr = new FileReader();
    fr.onload = onLoadFileHandler;
    fr.readAsText(file);
}
<input type='file' onchange='onChooseFile(event, onFileLoad.bind(this, "contents"))' />
<p id="contents"></p>


Не працює в Internet Explorer.
Мервей Муафак

4

Щасливого кодування!
Якщо ви отримаєте помилку в Internet Explorer, змініть налаштування безпеки, щоб дозволити ActiveX

var CallBackFunction = function(content)
{
    alert(content);
}
ReadFileAllBrowsers(document.getElementById("file_upload"), CallBackFunction); 

//Tested in Mozilla Firefox browser, Chrome
function ReadFileAllBrowsers(FileElement, CallBackFunction)
{
try
{
    var file = FileElement.files[0];
    var contents_ = "";

     if (file) {
        var reader = new FileReader();
        reader.readAsText(file, "UTF-8");
        reader.onload = function(evt)
        {
            CallBackFunction(evt.target.result);
        }
        reader.onerror = function (evt) {
            alert("Error reading file");
        }
    }
}
catch (Exception)
 {
    var fall_back =  ieReadFile(FileElement.value);
    if(fall_back != false)
    {
        CallBackFunction(fall_back);
    }
 }
}

///Reading files with Internet Explorer
function ieReadFile(filename)
{
 try
 {
    var fso  = new ActiveXObject("Scripting.FileSystemObject");
    var fh = fso.OpenTextFile(filename, 1);
    var contents = fh.ReadAll();
    fh.Close();
    return contents;
 }
 catch (Exception)
  {
    alert(Exception);
    return false;
  }
 }

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.