Чтение содержимого файла на стороне клиента в JavaScript в различных браузерах


Я пытаюсь предоставить сценарий-только решение для чтения содержимого файла на клиентской машине через браузер.

у меня есть решение, которое работает с 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 на данный момент, но я открыт для предложений для любого другого браузера.

Edit: в ответ на вопрос, "почему вы хотите это сделать?":

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

3 70

3 ответа:

отредактировано для добавления информации о файле API

так как я изначально написал этот ответ, то File API был предложен в качестве стандарта и реализовано в большинстве браузеров (начиная с IE 10, который добавил поддержку FileReader API, описанный здесь, хотя еще не File API). API немного сложнее, чем старый Mozilla API, так как он предназначен для поддержки асинхронного чтения файлов, лучшей поддержки двоичных файлов и декодирование различных текстовых кодировок. Есть некоторые документы доступны в Mozilla Developer Network а также различные примеры онлайн. Вы бы использовали его следующим образом:

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). Единственные ключи, которые a File объект имеет are fileName и fileSize. Согласно совершить сообщение для поддержки файлов и списков файлов они вдохновлены объект файла Mozilla, но они, кажется, поддерживают только подмножество функций.

если вы хотите изменить это, вы всегда можете отправить патч к проекту WebKit. Другая возможность могла бы заключаться в том, чтобы предложить компании Mozilla API для включения в HTML 5; the WHATWG список рассылки, вероятно, лучшее место для этого. Если вы это сделаете, то это гораздо более вероятно, что будет кросс-браузерный способ сделать это, по крайней мере, через пару лет. Конечно, отправка патча или предложения о включении в HTML 5 означает некоторую работу по защите идеи, но тот факт, что Firefox уже реализует ее, дает вам что-то для начала.

чтобы прочитать файл, выбранный пользователем, используя диалоговое окно открытия файла, вы можете использовать <input type="file"> тег. Вы можете найти информация об этом от MSDN. Когда файл выбран, вы можете использовать FileReader API читать содержание.

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, измените параметры безопасности, чтобы разрешить 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;
  }
 }