Yüklenen dosyanın mime türü tarayıcı tarafından nasıl belirlenir?


87

Kullanıcının bir .zip dosyası yüklemesi gereken bir web uygulamam var. Sunucu tarafında, application/x-zip-compressedya da olduğundan emin olmak için yüklenen dosyanın mime türünü kontrol ediyorum application/zip.

Bu benim için Firefox ve IE'de iyi çalıştı. Ancak, bir iş arkadaşı bunu test ettiğinde, Firefox'ta başarısız oldu (gönderilen mime türü " application/octet-stream" gibi bir şeydi ) ancak Internet Explorer'da çalıştı. Kurulumlarımız aynı görünüyor: Tüm eklentiler devre dışı bırakılmış IE8, FF 3.5.1, Win XP SP3, WinRAR yerel .zip dosyası işleyicisi olarak yüklenmiş (bunun alakalı olup olmadığından emin değilim).

Öyleyse sorum şu: Tarayıcı hangi mime türünü göndereceğini nasıl belirler?

Lütfen dikkat: Mime türünün tarayıcı tarafından gönderildiğini ve bu nedenle güvenilmez olduğunu biliyorum. Bunu bir kolaylık olarak kontrol ediyorum - esas olarak zip olmayan bir dosyayı zip dosyası olarak açmaya çalışarak elde ettiğinizden daha kolay bir hata mesajı vermek ve (muhtemelen ağır) zip dosyası kitaplıklarını yüklemekten kaçınmak için.


application / octet-stream bir ikili dosya belirtir. Bir zip dosyası olup olmadığını görmek için dosyanın uzantısını alabilmelisiniz. Sadece açıklığa kavuşturmak gerekirse, bu FF'de sizin için işe yaradı, ancak iş arkadaşınız işe yaramadı mı?
Kevin Crowell

evet, benim için her iki tarayıcıda da çalıştı
Kip

input/@formenctypeveya form/@enctypeniteliklerine bir göz atın
tuxSlayer

Yanıtlar:


72

Krom

Chrome (yazılırken sürüm 38) , MIME türünü belirlemenin 3 yolu vardır ve bunu belirli bir sırayla yapar. Aşağıdaki kod parçası dosya src/net/base/mime_util.ccyönteminden alınmıştır MimeUtil::GetMimeTypeFromExtensionHelper.

// We implement the same algorithm as Mozilla for mapping a file extension to
// a mime type.  That is, we first check a hard-coded list (that cannot be
// overridden), and then if not found there, we defer to the system registry.
// Finally, we scan a secondary hard-coded list to catch types that we can
// deduce but that we also want to allow the OS to override.

Sabit kodlanmış listeler dosyada biraz daha erken gelir: https://cs.chromium.org/chromium/src/net/base/mime_util.cc?l=170 ( kPrimaryMappingsve kSecondaryMappings).

Örnek: Microsoft Excel'in yüklü olduğu bir Windows sisteminden bir CSV dosyası yüklerken, Chrome bunu olarak bildirecektir application/vnd.ms-excel. Bunun nedeni .csv, ilk sabit kodlu listede belirtilmemesi, dolayısıyla tarayıcının sistem kayıt defterine geri dönmesidir. olarak ayarlanmış HKEY_CLASSES_ROOT\.csvbir değere sahiptir .Content Typeapplication/vnd.ms-excel

Internet Explorer

Yine aynı örneği kullanarak, tarayıcı rapor verecektir application/vnd.ms-excel. Internet Explorer'ın (yazarken sürüm 11) kayıt defterini kullandığını varsaymanın makul olduğunu düşünüyorum . Muhtemelen Chrome ve Firefox gibi sabit kodlanmış bir listeyi de kullanıyor, ancak kapalı kaynak niteliği doğrulamayı zorlaştırıyor.

Firefox

Chrome kodunda belirtildiği gibi, Firefox (yazarken sürüm 32) benzer şekilde çalışır. Dosyadan pasaj uriloader\exthandler\nsExternalHelperAppService.cpp, yöntemnsExternalHelperAppService::GetTypeFromExtension

// OK. We want to try the following sources of mimetype information, in this order:
// 1. defaultMimeEntries array
// 2. User-set preferences (managed by the handler service)
// 3. OS-provided information
// 4. our "extras" array
// 5. Information from plugins
// 6. The "ext-to-type-mapping" category

Sabit kodlanmış listeler dosyanın daha başında, 441 satırına yakın bir yerde gelir . defaultMimeEntriesVe extraMimeEntries.

Mevcut profilimle, tarayıcı rapor verecek text/csvçünkü bunun için bir giriş var mimeTypes.rdf(yukarıdaki listede öğe 2). Bu girişe sahip olmayan yeni bir profille, tarayıcı rapor verecektir application/vnd.ms-excel(listedeki öğe 3).

Özet

Tarayıcılardaki sabit kodlu listeler oldukça sınırlıdır. Genellikle, tarayıcı tarafından gönderilen MIME türü, işletim sistemi tarafından bildirilen tür olacaktır. Ve işte tam da bu yüzden, soruda belirtildiği gibi, tarayıcı tarafından bildirilen MIME türü güvenilmezdir.


1
Teşekkürler! krom kaynağındaki sabit kodlu listeye bir bağlantınız var mı?
Kip

@Kip evet, bir bağlantı ekledim. Firefox'un (resmi) bir çevrimiçi kaynak kodu tarayıcısı yok gibi görünüyor, onu FTP sunucularından indirmem gerekiyordu.
user247702

MIME'nin CSV için ms-excel olarak kullanılması can sıkıcıdır, neden sabit kodlu listede olmadığını merak edin.
Kris

2014'ten beri mime türü algılamada bazı güncellemeler olup olmadığını bilmek güzel olurdu.
Vitaly Isaev 05

1
@VitalyIsaev Chrome koduna hızlı bir bakış bunun 2014'ten beri değişmediğini gösteriyor.
user247702

12

Kip, RFC'leri, MSDN ve MDN'yi okumak için biraz zaman harcadım. İşte anlayabildiğim şey. Bir tarayıcı yüklenecek bir dosyayla karşılaştığında, aldığı ilk veri arabelleğine bakar ve ardından üzerinde bir test çalıştırır. Bu testler, dosyanın bilinen bir mime türü olup olmadığını belirlemeye çalışır ve eğer biliniyorsa, onu bilinen mime türü için daha fazla test edecek ve buna göre harekete geçecektir. Sanırım IE sadece dosya türünü uzantıdan belirlemek yerine bunu yapmaya çalışıyor. Bu sayfa bunu IE http://msdn.microsoft.com/en-us/library/ms775147%28v=vs.85%29.aspx için açıklamaktadır . Firefox için anlayabildiğim şey, dosya bilgisini dosya sisteminden veya dizin girişinden okumaya çalışması ve ardından dosya türünü belirlemesiydi. İşte FF için bir bağlantı https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIFile. Yine de bu konuda daha yetkili bilgilere sahip olmak istiyorum.


8

Bu muhtemelen işletim sistemine ve muhtemelen tarayıcıya bağlıdır, ancak Windows'ta, belirli bir dosya uzantısı için MIME türü, HKCR altındaki kayıt defterine bakılarak bulunabilir:

Örneğin:

HKEY_CLASSES_ROOT.zip - İçerik Türü

MIME'den dosya uzantısına gitmek için aşağıdaki tuşlara bakabilirsiniz.

HKEY_CLASSES_ROOT \ Mime \ Veritabanı \ İçerik Türü

Belirli bir MIME türü için varsayılan uzantıyı almak için.


Teşekkürler. ne yazık ki, hem ben hem de iş arkadaşım için kayıt defterimizde bu doğru görünüyor. sanırım bu yüzden onun için IE'de işe yaradı, ama FF onu bir şekilde farklı anlıyor ... peki :(
Kip

5

Bu sorunuzun cevabı olmasa da çözmeye çalıştığınız sorunu çözer. YMMV.

Sizin de yazdığınız gibi, mime türü güvenilir değildir, çünkü her tarayıcının onu belirleme yöntemi vardır. Ancak, tarayıcılar dosyanın orijinal adını (uzantı dahil) gönderir. Bu nedenle, sorunu çözmenin en iyi yolu, MIME türü yerine dosyanın uzantısını incelemektir.

Hala mime türüne ihtiyacınız varsa, bunu sunucu tarafında belirlemek için kendi apache'nizin mime.types'ini kullanabilirsiniz.


1
Detaylandırmak ister misin? Deneyimlerime göre, tarayıcılar her zaman doğru orijinal dosya adını (uzantı ile) gönderirken, MIME türleri büyük ölçüde değişiklik gösterir. Yani evet, çok daha güvenilir olduğunu söyleyebilirim.
johndodo

Doğru. Son kullanıcının, gerçek türüne bakılmaksızın herhangi bir uzantı ekleyebileceğini, bu nedenle güvenilmemesi gerektiğini söylemek istedim.
Djizeus

Bu doğrudur, ancak uzantı veya MIME türü kullanmanız önemli değildir - kullanıcı tarafından sağlanan girdiye asla güvenmemelisiniz. Ancak OP, bu sorunun farkında olduğunu açıkça belirtti, dolayısıyla bu, bu sorunun bir parçası değil. Btw, olumsuz oyu kaldırırsanız memnun olurum (sizden geldiğini varsayıyorum).
johndodo

Haklısın, söz konusu olmamasına dikkat etmedim, benim hatam.
Oyumu

Evet, johndodo'ya katılıyorum. Stijn'in yukarıdaki cevabında açıkladığı gibi, Chrome ve Firefox önce uzantıyı kontrol ediyor. Sonunda aynı şeyi yapıyorlar.
Jenix

0

Johndodo'ya katılıyorum, tarayıcılardan gönderilen mime türlerini güvenilmez kılan pek çok değişken var. Alınan alt türleri hariç tutar ve sadece 'uygulama' gibi türe odaklanırım. uygulamanız php tabanlıysa, bunu explode () işlevini kullanarak kolayca yapabilirsiniz. ek olarak, .zip veya aradığınız başka bir sıkıştırma olduğundan emin olmak için dosya uzantısını kontrol edin!


0

Rfc1867'ye göre - HTML'de form tabanlı dosya yükleme :

Ortam türü biliniyorsa (örneğin, dosya uzantısından veya işletim sistemi yazım bilgilerinden çıkarılırsa) veya uygulama / sekizli akışı olarak her parça uygun bir içerik türü ile etiketlenmelidir.

Yani benim anlayışım, eğer tür çıkarılamazsa , application/octet-streambir tür blanket catch-alltanımlayıcıya benzer .


evet, hepsini anlıyorum. soru, tarayıcının nasıl sonuç çıkaracağıydı.
Kip

Bilmeye değer, değil mi? Eğer application/octet-streamcatch-all, daha sonra başka bir yaklaşım alırsanız kendi sunucu tarafı testlerini bir tahmin yapmak mümkün olmuştur eğer tarayıcı güven ve yapmak olacaktır application/octet-stream.
MikeBeaton
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.