Saya memiliki aplikasi web tempat pengguna perlu mengunggah file .zip. Di sisi server, saya memeriksa jenis mime dari file yang diunggah, untuk memastikannya adalah application/x-zip-compressed
atau application/zip
.
Ini berfungsi dengan baik untuk saya di Firefox dan IE. Namun, saat rekan kerja mengujinya, ia gagal di Firefox (jenis pantomim yang dikirim adalah seperti " application/octet-stream
") tetapi bekerja di Internet Explorer. Setup kami tampaknya identik: IE8, FF 3.5.1 dengan semua add-on dinonaktifkan, Win XP SP3, WinRAR diinstal sebagai penangan file .zip asli (tidak yakin apakah itu relevan).
Jadi pertanyaan saya adalah: Bagaimana browser menentukan jenis mime yang akan dikirim?
Harap diperhatikan: Saya tahu bahwa jenis pantomim dikirim oleh browser dan, oleh karena itu, tidak dapat diandalkan. Saya hanya memeriksanya sebagai kemudahan - terutama untuk memberikan pesan kesalahan yang lebih bersahabat daripada yang Anda dapatkan dengan mencoba membuka file non-zip sebagai file zip, dan untuk menghindari memuat pustaka file zip (mungkin berat).
sumber
input/@formenctype
atauform/@enctype
atributJawaban:
Chrome
Chrome (versi 38 pada saat penulisan) memiliki 3 cara untuk menentukan jenis MIME dan melakukannya dalam urutan tertentu. Cuplikan di bawah ini berasal dari file
src/net/base/mime_util.cc
, metodeMimeUtil::GetMimeTypeFromExtensionHelper
.Daftar hard-coded muncul sedikit lebih awal di file: https://cs.chromium.org/chromium/src/net/base/mime_util.cc?l=170 (
kPrimaryMappings
dankSecondaryMappings
).Contoh: saat mengunggah file CSV dari sistem Windows dengan Microsoft Excel terpasang, Chrome akan melaporkannya sebagai
application/vnd.ms-excel
. Ini karena.csv
tidak ditentukan dalam daftar kode keras pertama, sehingga browser kembali ke registri sistem.HKEY_CLASSES_ROOT\.csv
memiliki nilai bernamaContent Type
yang disetel keapplication/vnd.ms-excel
.Internet Explorer
Sekali lagi menggunakan contoh yang sama, browser akan melaporkan
application/vnd.ms-excel
. Saya pikir masuk akal untuk menganggap Internet Explorer (versi 11 saat penulisan) menggunakan registri. Mungkin itu juga menggunakan daftar hard-coded seperti Chrome dan Firefox, tetapi sifatnya yang closed source membuatnya sulit untuk diverifikasi.Firefox
Seperti yang ditunjukkan dalam kode Chrome, Firefox (versi 32 pada saat penulisan) bekerja dengan cara yang sama. Cuplikan dari file
uriloader\exthandler\nsExternalHelperAppService.cpp
, metodensExternalHelperAppService::GetTypeFromExtension
Daftar hard-coded muncul lebih awal dalam file, dekat baris 441. Anda sedang mencari
defaultMimeEntries
danextraMimeEntries
.Dengan profil saya saat ini, browser akan melaporkan
text/csv
karena ada entri untuk profil itu dimimeTypes.rdf
(item 2 di daftar di atas). Dengan profil baru, yang tidak memiliki entri ini, browser akan melaporkanapplication/vnd.ms-excel
(item 3 dalam daftar).Ringkasan
Daftar hard-coded di browser sangat terbatas. Seringkali, jenis MIME yang dikirim oleh browser adalah yang dilaporkan oleh OS. Dan inilah tepatnya mengapa, seperti yang dinyatakan dalam pertanyaan, tipe MIME yang dilaporkan oleh browser tidak dapat diandalkan.
sumber
Kip, saya menghabiskan beberapa waktu membaca RFC, MSDN dan MDN. Inilah yang bisa saya pahami. Saat browser menemukan file untuk diunggah, browser melihat buffer pertama dari data yang diterimanya dan kemudian menjalankan pengujian padanya. Tes ini mencoba untuk menentukan apakah file tersebut adalah jenis pantomim yang dikenal atau bukan, dan jika jenis pantomim diketahui, ia hanya akan mengujinya lebih lanjut untuk jenis pantomim yang diketahui dan mengambil tindakan yang sesuai. Saya pikir IE mencoba melakukan ini terlebih dahulu daripada hanya menentukan jenis file dari ekstensi. Halaman ini menjelaskan hal ini untuk IE http://msdn.microsoft.com/en-us/library/ms775147%28v=vs.85%29.aspx . Untuk firefox, yang dapat saya pahami adalah mencoba membaca info file dari sistem file atau entri direktori dan kemudian menentukan jenis file. Ini adalah tautan untuk FF https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIFile. Saya masih ingin mendapatkan info lebih resmi tentang ini.
sumber
Ini mungkin OS dan mungkin bergantung pada browser, tetapi pada Windows, tipe MIME untuk ekstensi file tertentu dapat ditemukan dengan melihat di registri di bawah HKCR:
Sebagai contoh:
HKEY_CLASSES_ROOT.zip - JenisKonten
Untuk beralih dari MIME ke ekstensi file, Anda dapat melihat tombol di bawah
HKEY_CLASSES_ROOT \ Mime \ Database \ Jenis Konten
Untuk mendapatkan ekstensi default untuk jenis MIME tertentu.
sumber
Meskipun ini bukan jawaban untuk pertanyaan Anda, ini memecahkan masalah yang Anda coba selesaikan. YMMV.
Seperti yang Anda tulis, jenis pantomim tidak dapat diandalkan karena setiap browser memiliki cara untuk menentukannya. Namun, browser mengirimkan nama asli (termasuk ekstensi) dari file tersebut. Jadi cara terbaik untuk mengatasi masalah ini adalah dengan memeriksa ekstensi file, bukan tipe MIME.
Jika Anda masih membutuhkan jenis mime, Anda dapat menggunakan mime.types apache Anda sendiri untuk menentukannya di sisi server.
sumber
Saya setuju dengan johndodo, ada banyak sekali variabel yang membuat jenis mime yang dikirim dari browser tidak bisa diandalkan. Saya akan mengecualikan subtipe yang diterima dan hanya fokus pada tipe seperti 'aplikasi'. jika aplikasi Anda berbasis php, Anda dapat dengan mudah melakukan ini dengan menggunakan fungsi explode (). selain itu, cukup periksa ekstensi file untuk memastikannya .zip atau kompresi lain yang Anda cari!
sumber
Menurut rfc1867 - Unggahan file berbasis formulir dalam HTML :
Jadi pemahaman saya adalah,
application/octet-stream
ini sepertiblanket catch-all
pengenal jika jenisnya tidak dapat disimpulkan .sumber
application/octet-stream
bersifat catch-all, maka pendekatan lain adalah mempercayai browser jika browser tersebut dapat menebak, dan melakukan pengujian sisi server Anda sendiri jika mendapatkannyaapplication/octet-stream
.