İstemci tarafındaki dosya içeriklerini çeşitli tarayıcılarda javascript'te okuma


113

Bir istemci makinesindeki bir dosyanın içeriğini tarayıcı aracılığıyla okumak için yalnızca komut dosyası içeren bir çözüm sağlamaya çalışıyorum.

Firefox ve Internet Explorer ile çalışan bir çözümüm var. Hoş değil, ama şu anda sadece bir şeyler deniyorum:

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 :(";
    }
}

Arayabilirim getFileContents()ve içeriği fileContentsmetin alanına yazacaktır .

Bunu diğer tarayıcılarda yapmanın bir yolu var mı?

Şu anda en çok Safari ve Chrome ile ilgileniyorum, ancak başka herhangi bir tarayıcı için önerilere açığım.

Düzenleme: "Bunu neden yapmak istiyorsunuz?" Sorusuna yanıt olarak:

Temel olarak, dosya içeriğini istemci tarafında tek seferlik bir parola ile birlikte hash hale getirmek istiyorum, böylece bu bilgileri doğrulama olarak geri gönderebilirim.


Bir cevabım olduğundan değil ama sadece açıklık adına, dosyanın yerini bilmeniz gerekiyor mu? Değilse, dosyanın konumunun bir dosya girişinden okunması gerekiyor mu yoksa bir metin kutusu / metin alanı / her neyse olabilir mi?
Darko Z

İyi soru. Hayır, dosyanın nereden geldiği gerçekten umrumda değil, sadece içeriği. Bir dosya girdisi kullanmak bana mantıklı geliyor ama yerel html olduğu için yapmam gereken bir şey daha var.
Damovisa

neden bunu yapmak istiyorsun? sunucu bunu yapmak içindir.
geowa4

Tamam, kısaca: Bir kullanıcı bir şifre girer ve bir dosya seçer. Parola dosya içeriğiyle karıştırılır ve bu dosya ile birlikte sunucuya gönderilir. Oraya ulaştığında, doğru istemci şifresinin kullanıldığını doğrulayabilirim.
Damovisa

Yanıtlar:


159

Dosya API'si hakkında bilgi eklemek için düzenlendi

Bu cevabı ilk yazdığımdan beri, Dosya API'si bir standart olarak önerildi ve çoğu tarayıcıda uygulandı ( FileReaderburada açıklanan API için destek ekleyen IE 10'dan itibaren , ancak henüz FileAPI değil ). API, dosyaların eşzamansız okunmasını, ikili dosyalar için daha iyi desteği ve farklı metin kodlamalarının kodlarının çözülmesini desteklemek için tasarlandığından, eski Mozilla API'sinden biraz daha karmaşıktır. Orada bazı Mozilla Geliştirici Ağı'nda mevcut belgeler çevrimiçi yanı sıra çeşitli örnekler. Aşağıdaki gibi kullanırsınız:

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";
    }
}

Orijinal cevap

WebKit'te bunu yapmanın bir yolu yok gibi görünüyor (dolayısıyla, Safari ve Chrome). Bir File nesnesinin sahip olduğu tek anahtar fileNameve fileSize. File ve FileList desteğinin commit mesajına göre , bunlar Mozilla'nın File nesnesinden esinlenmiştir , ancak özelliklerin yalnızca bir alt kümesini destekliyor gibi görünmektedir.

Bunu değiştirmek isterseniz , WebKit projesine her zaman bir yama gönderebilirsiniz . Başka bir olasılık, Mozilla API'sini HTML 5'e dahil edilmek üzere önermektir ; WHATWG posta listesi muhtemelen bunun için en iyi yerdir. Bunu yaparsanız, en azından birkaç yıl içinde, bunu yapmanın çapraz tarayıcı bir yolu olması çok daha olasıdır. Elbette, HTML 5'e bir yama veya bir teklif göndermek, fikri savunan bazı çalışmalar anlamına gelir, ancak Firefox'un bunu zaten uyguladığı gerçeği size başlangıç ​​için bir şeyler verir.


Bunun için teşekkürler - Bu noktada bir yama göndermek için yeterince kararlı olduğumu sanmıyorum. Bu, muhtemelen bilginiz olmadan olmasını istemeyeceğiniz bir şey. Tarayıcının
korumalı

4
Bu dosyayı yüklemeyi kasıtlı olarak seçtiğiniz için tarayıcı sanal alanını bozmaz; sunucuya ulaşabilirse, sadece fazladan bir gidiş dönüş ile tarayıcıya geri dönebilir. Çevrimdışı modun web uygulamaları için çalışmasını sağlayacak çalışma göz önüne alındığında, bu makul bir özellik olacaktır.
Brian Campbell

Mm, aslında bu adil bir nokta. Bu dosyayı seçmek için kullanıcı etkileşimi vardı. Teşekkürler.
Damovisa

@Damovisa Hala bunu önemsiyor musunuz bilmiyorum, ancak aradığınız şeyi yapan ve Firefox, Chrome ve gece sürümlerinde uygulanan yeni Dosya API'sinden bahsetmek için cevabımı güncelleyeceğimi düşündüm. Safari.
Brian Campbell

Harika, bunun için teşekkürler. Başka bir işe geçtim, ama cevabın orada olduğunu bilmek güzel :)
Damovisa

25

Kullanıcı tarafından seçilen bir dosyayı okumak için, dosya açma iletişim kutusunu kullanarak <input type="file">etiketini kullanabilirsiniz . Bununla ilgili bilgileri MSDN'de bulabilirsiniz . Dosya seçildiğinde , içeriği okumak için Dosya Okuyucu API'sini kullanabilirsiniz.

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'da çalışmıyor.
Merwais Muafaq

4

Mutlu kodlamalar!
Internet Explorer'da bir hata alırsanız, ActiveX'e izin vermek için güvenlik ayarlarını değiştirin.

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;
  }
 }

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.