<İnput type = “file”> kullanılırken dosya biçimi sınırlandırılsın mı?


667

Kullanıcı <input type="file">HTML'deki öğedeki Gözat düğmesini tıklattığında yerel işletim sistemi dosya seçicisinden seçilebilecek dosya türünü kısıtlamak istiyorum . Ben imkansız bir his var, ama orada olmadığını bilmek istiyorum olan bir çözüm. Yalnızca HTML ve JavaScript'e bağlı kalmak istiyorum; Flash yok lütfen.


1
PHP ile kolayca mümkündür, ama bu yüzden eğer kod yayınlamak olmaz bunu kullanabilirsiniz bilmiyorum.
Latox

2
Yapabilirim, ancak JavaScript ile çalışan bir çözümüm var - bir dosyayı karşıya yükleme ve ardından "Yanlış dosya!" hata.
Bojangles

Ayrıca daha yeni bir soruya bakın: stackoverflow.com/questions/181214/…
Christophe Roussy

Dikkat edilmesi gereken bir şey, doğrulama için harika olmasa da, kabul et, kullanıcılara göz atarken görünür dosyaları kabul edilen dosyalarla sınırlayacaktır (en azından bazı tarayıcılarda ...). Yani bu bir doğrulamadan çok bir UI ergonomi özelliğidir.
Christophe Roussy

Yanıtlar:


1119

Açıkçası, cevap hayır . Bir geliştirici , kullanıcının herhangi bir türde veya uzantıda dosya yüklemesini engelleyemez.

Ancak yine de, öğesinin accept özelliği <input type = "file">, işletim sisteminin dosya seçimi iletişim kutusunda bir filtre sağlanmasına yardımcı olabilir. Örneğin,

<!-- (IE 10+, Edge (EdgeHTML), Edge (Chromium), Chrome, Firefox 42+) -->
<input type="file" accept=".xls,.xlsx" />

.xls veya .xlsx dışındaki dosyaları filtrelemek için bir yol sağlamalıdır. Öğe için MDN sayfası inputher zaman bunu desteklediğini söylese de, sürpriz olarak, bu sürüm 42'ye kadar Firefox'ta benim için işe yaramadı. Bu IE 10+, Edge ve Chrome'da çalışıyor.

IE 10+, Edge, Chrome ve Opera ile birlikte 42'den eski Firefox'u desteklemek için, sanırım MIME türlerinin virgülle ayrılmış listesini kullanmak daha iyidir:

<!-- (IE 10+, Edge (EdgeHTML), Edge (Chromium), Chrome, Firefox) -->
<input type="file"
 accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel" /> 

[ Edge (EdgeHTML) davranışı: Dosya türü filtresi açılır menüsü, burada belirtilen dosya türlerini gösterir, ancak açılır menüdeki varsayılan değer değildir. Varsayılan filtre şudur All files (*).]

MIME türlerinde yıldız işaretleri de kullanabilirsiniz. Örneğin:

<input type="file" accept="image/*" /> <!-- all image types --> 
<input type="file" accept="audio/*" /> <!-- all audio types --> 
<input type="file" accept="video/*" /> <!-- all video types --> 

W3C, yazarlara özellikte hem MIME türlerini hem de karşılık gelen uzantıları belirtmelerini öneriraccept . Yani, en iyi yaklaşım:

<!-- Right approach: Use both file extensions and corresponding MIME-types. -->
<!-- (IE 10+, Edge (EdgeHTML), Edge (Chromium), Chrome, Firefox) -->
<input type="file"
 accept=".xls,.xlsx, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,application/vnd.ms-excel" /> 

JSFiddle aynı: burada .

Başvuru: MIME türlerinin listesi

ÖNEMLİ:accept Özniteliğin kullanılması, yalnızca ilgilenilen tür dosyalarına filtre uygulamak için bir yol sağlar. Tarayıcılar yine de kullanıcıların herhangi bir türde dosya seçmesine izin verir. Ek (istemci tarafında) kontroller yapılmalıdır (JavaScript kullanarak, tek yol olacaktır bu ), ve kesinlikle dosya türlerini sunucuda doğrulanacak GEREKİR (dosya uzantısı ve onun ikili imza ikisini de kullanarak MIME tipi bir arada kullanarak, ASP .NET , PHP , Ruby , Java ). Ayrıca dosya türleri ve sihirli numaraları için bu tablolara başvurmak isteyebilirsiniz, daha sağlam bir sunucu tarafı doğrulaması yapmak için.

İşte dosya yüklemeleri ve güvenlik hakkında üç iyi okuma .

DÜZENLEME: İkili imzasını kullanarak dosya türü doğrulaması HTML5 Dosya API'sı kullanılarak JavaScript kullanılarak (yalnızca uzantıya bakmak yerine) istemci tarafında da yapılabilir, ancak yine de dosyanın kötü niyetli bir kullanıcı tarafından doğrulanması gerekir. yine de özel bir HTTP isteği yaparak dosya yükleyebilir.


2
@Sandesire HTML'deki dosya boyutlarını kısıtlayabileceğinizi düşünmüyorum. Önerdiğiniz gibi JavaScript kullanmak mümkündür.
Sachin Joseph

1
Kişisel deneyimime göre bu iyi bir yanıt gibi görünüyor, mime türü tek başına tüm tarayıcılarda çalışmaz.
Christophe Roussy

1
Bu arada acceptEdge'de hala çalışmıyor: stackoverflow.com/questions/31875617/… . Daha fazla ayrıntı için: wpdev.uservoice.com/forums/257854-microsoft-edge-developer/…
SharpC

1
Örneğin dosyaları hariç tutma seçeneğimiz olsaydı exclude="exe". ¯_ (ツ) _ / ¯
Sagiv bg

1
Edge davranışını daha fazla açıklamak için (testlerime göre), belirttiğinize göre farklı filtreler ekler, ancak a) paketlenmez, bu nedenle her uzantıyı ayrı bir seçenek olarak listeler ve b) her zaman .html ve c) gibi uzantılar oluşturduğunuzda, her zaman önceden (*) seçilir. Bu büyük bir karmaşa ve çoğu durumda işe yaramaz hale getirir. Uservoice bağlantısına oy verdim, umarım er ya da geç dinlerler.
Arie

198

Giriş etiketi için kabul özelliği vardır. Ancak, hiçbir şekilde güvenilir değildir. Tarayıcılar bunu büyük olasılıkla "öneri" olarak görür, yani kullanıcı, dosya yöneticisine bağlı olarak, yalnızca istenen türleri görüntüleyen bir ön seçime sahip olur. Yine de "tüm dosyalar" ı seçebilir ve istedikleri dosyayı yükleyebilirler.

Örneğin:

<form>
    <input type="file" name="pic" id="pic" accept="image/gif, image/jpeg" />
</form>

HTML5 spesifikasyonunda daha fazla bilgi edinin

Yalnızca kullanıcının doğru dosyaları bulmasının "yardım" olarak kullanılması gerektiğini unutmayın. Her kullanıcı istediği herhangi bir talebi sunucunuza gönderebilir. Sunucu tarafındaki her şeyi her zaman doğrulamanız gerekir.

Cevap Yani: hayır sen kısıtlayamaz , ancak olabilir ve ön seçimli set ama olamaz ona bağlı.

Alternatif olarak veya ek olarak, dosya adını (giriş alanının değeri) JavaScript ile kontrol ederek benzer bir şey yapabilirsiniz, ancak bu koruma değildir ve kullanıcı için seçimi kolaylaştırmaz. Bir web yöneticisini yalnızca korunduğunu düşünmesi için kandırır ve bir güvenlik açığı açar. Alternatif dosya uzantılarına (örneğin jpg yerine jpeg), büyük harflere veya hiçbir dosya uzantısına (Linux sistemlerinde yaygın olarak) sahip olan kullanıcılar için eşek için bir acı olabilir.



1
Her ne kadar kullanıcının sonunda HERHANGİ bir dosya türünü seçmesini engellemek imkansız olduğu doğru olsa da, bu günlerde HTML5 Dosya API'sından yararlanabilir ve tespit etmek de dahil olmak üzere sunucuya yüklenmeden önce seçilen dosyayla yükleme için çalışabilirsiniz. türü, boyutu ve daha fazlası. Bir şans ver. Kullanımı çok kolay, ancak çok güçlü ve kullanışlı.
TheCuBeMan

96

Sen kullanabilirsiniz changehangi kullanıcı seçer izlemek ve dosya kabul edilebilir olmadığını bu noktada bildirmek üzere olay. Görüntülenen dosyaların gerçek listesini sınırlamaz, ancak desteklenmeyen acceptözelliğin yanı sıra istemci tarafında yapabileceğiniz en yakın dosyadır.

var file = document.getElementById('someId');

file.onchange = function(e) {
  var ext = this.value.match(/\.([^\.]+)$/)[1];
  switch (ext) {
    case 'jpg':
    case 'bmp':
    case 'png':
    case 'tif':
      alert('Allowed');
      break;
    default:
      alert('Not allowed');
      this.value = '';
  }
};
<input type="file" id="someId" />

JSFiddle


11
@joe, bu bir örnektir ... izin vermek istediğiniz uzantıları kapsayabilir.
Gabriele Petrioli

Evet yapabilirsin. ama sen BÖYLEMEDİN! ve maby biri zaten kopyaladı! ve doğru mime tipine sahip ancak uzantısız dosyalar ne olacak?
Surrican

49
@Joe .. şey .. ben yön ve sağlam bir mantık sağlamaya çalışıyorum. Her durum için tam olarak uygulanmamış çözümler. Web'den kod kopyalarken / yapıştırırken izleyicilerin sağduyusunu kullanmalarına güveniyorum;)
Gabriele Petrioli

7
"Some.File.jpg" nasıl olur? Belki de normal ifade satırının okuması gerekir: var ext = this.value.match (/ \. ([^.] +) $ /) [1];
Jon Kloske

Bu yaklaşımla ilgili sorun, bir şeyin o uzantıyla bitmese bile teknik olarak bir jpeg olabileceğidir. Uzantılar! == MIME türleri
Matt Fletcher

46

Evet haklısın. HTML ile imkansız. Kullanıcı istediği dosyayı seçebilir.

Bir dosyayı uzantısına göre göndermekten kaçınmak için bir parça JavaScript kodu yazabilirsiniz . Ancak bunun kötü niyetli bir kullanıcının gerçekten istediği herhangi bir dosyayı göndermesini engellemeyeceğini unutmayın.

Gibi bir şey:

function beforeSubmit()
{
    var fname = document.getElementById("ifile").value;
    // check if fname has the desired extension
    if (fname hasDesiredExtension) {
        return true;
    } else {
        return false;
    }
}

HTML Kodu:

<form method="post" onsubmit="return beforeSubmit();">
    <input type="file" id="ifile" name="ifile"/>
</form>

3
bunun için tamamen geçerli bir html özelliği vardır, bu yüzden mümkündür. sadece tarayıcılar tarafından saygı görmüyor, ama bu bir standardizasyon sorunu. yanı sıra korumasız biçimlendirme istemci tarafında işlenen herhangi bir şey herhangi bir şey kısıtlayamaz java script çözüm değildir.
Surrican

2
Çok iyi bir nokta. Her ihtimale karşı ikinci bir PHP denetleyicisi ekleyeceğim. Çok dikkatli olamazsınız!
Bojangles

2
Ben de bir PHP doğrulama komut dosyası kullanıyorsam hiçbir zarar vermez, bu yüzden her ikisini de kullanacağım.
Bojangles

17
@ Joe: Cevabımın berbat olduğunu söylemeyi bırak! :-) Her neyse, mükemmel bir çözüm değil. Başlangıçta söylediğim gibi: OP'nin istediklerini yapmak “imkansız”. Ama olabilir bazı yalnızca ona izin verirsen kullanıcı için yardım derecesini / onu belirli uzantılara sahip dosyaları seçin. GERÇEK dosya türü doğrulaması sunucu tarafında yapılmalıdır .
Pablo Santa Cruz

11
@JoeHopfgartner: Dostum, burada Pablo'ya karşı aşırı sert davranıyorsun. istemcinin validasyonu tonlarca yerde yapılır ve kusursuz olmamasına rağmen ([b] her zaman [/ b] sunucu tarafı validasyonu dahil edilmelidir) kullanıcıyı oldukça zamandan kurtarabilir (aptal bir uzatma kontrolü vb. için geri dönüş yok). Pablo tarafından verilen komut dosyası mükemmel olmasa da, yalnızca bu sorunun nasıl çözüleceğinin bir örneği olması amaçlanmıştır ... Belki de Microsoft'a teknoloji adamlarını e-postayla göndermeli ve ASP.NET doğrulayıcılarından Clientside doğrulamasını kaldırmasını istemelisiniz. her şey senin için saçmalık ...
Nathan

18

Teknik olarak, öğe üzerinde acceptözelliği ( html5'te alternatif ) belirtebilirsiniz input, ancak düzgün desteklenmez.


W3Schools tarayıcı desteği başarısız! Gerçekten utanç verici. Aynı zamanda bir güvenlik endişesidir - insanlar istemci tarafı kodunu hackleyebilir ve istedikleri her şeyi yükleyebilir.
Bojangles

5
Doğru, bunu güvenlik için kullanmamak en iyisidir, ancak kesinlikle destekleyen tarayıcılarda kullanılabilirliğe kesinlikle yardımcı olur. Kullanıcılar yalnızca sitenin izin verdiği dosyaları gösterir (aynı klasörde olabilecek tüm diğer önemsiz dosyaları değil) ve bir hata vermek için tüm yükleme işleminden geçmek zorunda kalmazlar, hemen bileceklerdir. Kodlayıcılar bunu kullanmalıdır.
Simon East

10

Kullanım inputiçeren etiketi acceptözniteliği

<input type="file" name="my-image" id="image" accept="image/gif, image/jpeg, image/png" />

En son tarayıcı uyumluluk tablosu için burayı tıklayın

Burada canlı demo

Yalnızca görüntü dosyalarını seçmek için bunu kullanabilirsiniz accept="image/*"

<input type="file" name="my-image" id="image" accept="image/*" />

Burada canlı demo

Yalnızca gif, jpg ve png gösterilecek, Chrome 44 sürümünden ekran yakalama Yalnızca gif, jpg ve png gösterilecek, Chrome 44 sürümünden ekran yakalama


Teşekkürler! Win10'daki Chrome'da, kullanırsam accept="image/*", dosya seçicideki "Özel Dosyalar" yerine "Görüntü Dosyaları" yazıyor, bu da son kullanıcı için iyi.
Teddy

Ancak kullanıcı bunu değiştirebilir ve diğer uzantı dosyasını yükleyebilir
Prashant Prajapati

@PrashantPrajapati Evet, tarayıcılar bu şekilde yapılır, sunucuda karşılık gelen doğrulama olmalıdır.Browser işlevselliği sadece daha iyi kullanıcı deneyimi içindir.
kiranvj

9

Bunun biraz geç olduğunu biliyorum.

function Validatebodypanelbumper(theForm)
{
   var regexp;
   var extension =     theForm.FileUpload.value.substr(theForm.FileUpload1.value.lastIndexOf('.'));
   if ((extension.toLowerCase() != ".gif") &&
       (extension.toLowerCase() != ".jpg") &&
       (extension != ""))
   {
      alert("The \"FileUpload\" field contains an unapproved filename.");
      theForm.FileUpload1.focus();
      return false;
   }
   return true;
}

5

Aslında javascript ile yapabilirsiniz, ancak js istemci tarafı olduğunu unutmayın, bu yüzden aslında bazı dosya türlerinden KAÇINMAK (söylediğiniz gibi kısıtlayın veya sınırlayın) gerçekten ne tür dosyaları yükleyebilirsiniz "uyarı" olurdu sunucu tarafı yapın.

Sunucu tarafı doğrulamaya başlamak istiyorsanız bu temel tutuma bakın . Tüm eğitim için bu sayfayı ziyaret edin .

İyi şanslar!


4

Önceki yanıtlarda belirtildiği gibi, kullanıcıyı yalnızca belirli dosya formatları için dosya seçmeye kısıtlayamayız. Ancak, html'deki dosya özniteliğindeki kabul etiketini kullanmak gerçekten kullanışlıdır.

Doğrulamaya gelince, bunu sunucu tarafında yapmalıyız. Biz de js istemci tarafında yapabiliriz ama kusursuz bir çözüm değil. Sunucu tarafında doğrulama yapmalıyız.

Bu gereksinimler için struts2 Java web uygulaması geliştirme çerçevesini tercih ediyorum. Yerleşik dosya yükleme özelliği ile struts2 tabanlı web uygulamalarına dosya yüklemek çok kolay. Sadece başvurumuzda kabul etmek istediğimiz dosya formatlarını belirtin ve geri kalan her şey çerçevenin özü tarafından halledilir. Struts resmi sitesinde kontrol edebilirsiniz.


3

Aşağıdakileri önerebilirim:

  • Kullanıcıya varsayılan olarak görüntü dosyalarından birini seçmesi gerekiyorsa, use accept = "image / *"

    <input type="file" accept="image/*" />

  • belirli görüntü türleriyle kısıtlamak istiyorsanız, accept = "image / bmp, image / jpeg, image / png" kullanın

    <input type="file" accept="image/bmp, image/jpeg, image/png" />

  • belirli türlerle kısıtlamak istiyorsanız accept = ". bmp, .doc, .pdf" kullanın

    <input type="file" accept=".bmp, .doc, .pdf" />

  • Kullanıcıyı dosya denetleyicisini tüm dosyalarla değiştiremez, bu nedenle komut dosyasında ve sunucudaki dosya türünü her zaman doğrulayın


1
Aradığım şey buydu: accept = ". Bmp" Krom üzerinde iyi çalışıyor.
MichaelRom
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.