今天項目上遇到了一個問題,用戶須要導入一個從咱們服務器上下載的EXCEL文件,前端根據獲取到的文件的type屬性進行判斷是否能夠上傳["application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "application/vnd.ms-excel"]
,可是在某一個用戶的電腦上卻出現了經過<input type="file">
獲取到的file對象中,type屬性爲"",因而開始找各類資料但願瞭解瀏覽器是如何獲取這個type屬性的,爲何同一個文件不一樣的電腦獲取到的屬性不同。前端
根據MDN上的說明,MIME Type (Multipurpose Internet Mail Extensions (MIME) type)是一種標準化的方式來表示文檔的性質和格式。它在IETF RFC 6838中進行了定義和標準化。
瀏覽器一般使用MIME類型(而不是文件擴展名)來肯定如何處理文檔;所以服務器設置正確以將正確的MIME類型附加到響應對象的頭部是很是重要的。因此瀏覽器中<input type="file">
獲取到的file對象中的type屬性實際上是文件的MIME Type。算法
在chromium開源代碼中 https://cs.chromium.org/chromium/src/net/base/mime_util.cc?l=314 314-318行中提到了:瀏覽器
// 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.
Chrome實現了與Mozilla相同的算法,將文件擴展名映射到MIME類型。
首先,Chrome會檢測一個硬編碼列表(不能被覆蓋)源碼中的kPrimaryMappings
,而後若是沒有找到符合的,Chrome會從操做系統註冊表中找,最後會掃描一個二級硬編碼列表,源碼中的kSecondaryMappings
,用來捕獲能夠推斷可是也但願容許操做系統覆蓋的類型。
例如:從安裝了Microsoft Excel的Windows系統上傳CSV文件時,Chrome會將其報告爲application/vnd.ms-excel
。這是由於.csv
未在第一個硬編碼列表中指定,所以瀏覽器會回退到系統註冊表。HKEY_CLASSES_ROOT\.csv
有一個名爲的值Content Type
設置爲application/vnd.ms-excel
。服務器
前言中遇到的問題瀏覽器中獲取不到type屬性不必定是代碼的緣由,而是系統中所安裝的Microsoft Excel軟件或註冊表的緣由,另外在MDN中的File對象中也找到這也一句描述:基於當前的實現,瀏覽器不會實際讀取文件的字節流,來判斷它的媒體類型。它基於文件擴展來假設;重命名爲 .txt 的 PNG 圖像文件爲 "text/plain" 而不是 "image/png" 。並且,file.type 僅僅對常見文件類型可靠。例如圖像、文檔、音頻和視頻。不常見的文件擴展名會返回空字符串。開發者最好不要依靠這個屬性,做爲惟一的驗證方案。app