JavaScript判斷文件類(lèi)型三種方法詳解
js判斷文件類(lèi)型詳解
通過(guò)file的type屬性判斷
<input type="file" onchange="onchangecb(this)" /> <script> function onchangecb(e) { const file = e.files[0]; console.log(file.type); } </script>
像html
中input
標(biāo)簽,就是根據(jù)選擇文件的后綴來(lái)生成一個(gè)File
對(duì)象。
像下面的幾種文件:
txt
文件:
jpg
文件:
mp4
文件:
使用文件后綴來(lái)判斷
function onchangecb(e) { const file = e.files[0]; //獲取最后一個(gè).的位置 const index= file.name.lastIndexOf("."); //獲取后綴 const ext = file.name.substr(index+1); console.log(ext); }
在得到文件后綴名后,根據(jù)后綴即可判斷文件的類(lèi)型(文件格式)。比如需要判斷一個(gè)文件是否是圖片格式,首先定義一個(gè)判斷函數(shù):
function isImage(ext) { return [ 'png', 'jpg', 'jpeg', 'bmp', 'gif', 'webp', 'psd', 'svg', 'tiff']. indexOf(ext.toLowerCase()) !== -1; }
雖然可以直接通過(guò)對(duì)象的type
屬性或者文件后綴來(lái)獲取文件類(lèi)型,但是如果強(qiáng)行修改文件后綴,同樣可以將其他類(lèi)型的文件上傳至服務(wù)器,或者文件壓根就沒(méi)有后綴,那又要怎么判斷呢?因此前端需要使用一個(gè)更加合理的方式。
根據(jù)二進(jìn)制流及文件頭來(lái)判斷
雖然文件后綴可以手動(dòng)改,因此可以直接通過(guò)讀取文件的二進(jìn)制來(lái)判斷。
通常來(lái)說(shuō)固定類(lèi)型的文件頭都是相同的,比如說(shuō)jpeg
的文件頭是FF D8 FF E0
。
這里提供一些常用的文件頭:
const fileMap = { JPEG: "FF D8 FF E0", JPG: "FF D8 FF E1", PNG: "89 50 4E 47", GIF: "47 49 46 38", TIFF: "49 49 2A 00", BMP: "42 4D", DWG: "41 43 31 30", PSD: "38 42 50 53", RTF: "7B 5C 72 74 66", XML: "3C 3F 78 6D 6C", HTML: "68 74 6D 6C 3E", EML: "44 65 6C 69 76 65 72 79 2D 64 61 74 65 3A", DBX: "CF AD 12 FE C5 FD 74 6F", PST: "21 42 44 4E", XLS: "D0 CF 11 E0", DOC: "D0 CF 11 E0", MDB: "53 74 61 6E 64 61 72 64 20 4A", WPD: "FF 57 50 43", PDF: "25 50 44 46 2D 31 2E", QDF: "AC 9E BD 8F", PWL: "E3 82 85 96", ZIP: "50 4B 03 04", RAR: "52 61 72 21", WAV: "57 41 56 45", AVI: "41 56 49 20", RAM: "2E 72 61 FD", RM: "2E 52 4D 46", MPG: "00 00 01 BA", MPG: "00 00 01 B3", MOV: "6D 6F 6F 76", ASF: "30 26 B2 75 8E 66 CF 11", MID: "4D 54 68 64", MP3: "49 44 33", };
通過(guò)onchange
方法獲取到選擇的文件后,使用FileReader
讀取文件的二進(jìn)制,之后判斷二進(jìn)制的前幾位是否跟符合相應(yīng)類(lèi)型文件的文件頭。
以下是一些使用文件頭來(lái)判斷文件類(lèi)型的簡(jiǎn)單代碼
// 判斷文件后綴與該文件內(nèi)容是否相同類(lèi)型 async function isSameFileType(file) { const suffix = getFileSuffix(file.name).toUpperCase(); const fileBlobString = await blobToString(file.slice(0, 14)); // 如果文件類(lèi)型中沒(méi)有該類(lèi)型,默認(rèn)為false if (!(suffix in fileMap)) { return false; } return fileBlobString.includes(fileMap[suffix]); } async function blobToString(blob) { return new Promise((resolve) => { const reader = new FileReader(); reader.onload = function () { const ret = reader.result .split("") // 分隔開(kāi) .map((v) => v.charCodeAt()) // 循環(huán)返回指定位置的字符的 Unicode 編碼 .map((v) => v.toString(16).toUpperCase()) // 返回十六進(jìn)制格式 .map((v) => v.padStart(2, "0")) // 給空的那個(gè)填充 00 ,防止空缺 .join(" "); // 每個(gè)子節(jié)之間空格隔開(kāi) resolve(ret); }; reader.readAsBinaryString(blob); // 調(diào)用之后觸發(fā)onload事件 }); // 二進(jìn)制=》ascii碼=》轉(zhuǎn)成16進(jìn)制字符串 } // 獲取文件后綴 function getFileSuffix(filename) { return filename.substring(filename.lastIndexOf(".") + 1, filename.length); }
判斷是否是png
類(lèi)型:
async function isPng(file) { // 同理 const ret = await blobToString(file.slice(0, 4)); const ispng = ret === fileMap.PNG; return ispng; }
當(dāng)然也可以針對(duì)圖片高寬進(jìn)行限制:
在png
二進(jìn)制中,第18-20位是圖片的寬,22-24是高。
獲取圖片寬高:
function getRectByOffset(file, widthOffset, heightOffset, reverse) { let width = await blobToString(file.slice(...widthOffset)); let height = await blobToString(file.slice(...heightOffset)); const w = parseInt(width.replace(" ", ""), 16); const h = parseInt(height.replace(" ", ""), 16); return { w, h }; }
修改一下之前判斷isPng
的方法,加上高寬限制
const IMG_WIDTH_LIMIT = 1000; const IMG_HEIGHT_LIMIT = 800 function isPng(file) { // 同理 const ret = await this.blobToString(file.slice(0, 4)); const ispng = ret === fileMap.PNG; if (ispng) { const { w, h } = await this.getRectByOffset(file, [18, 20], [22, 24]); console.log(`png 寬高 ${w},${h}`); if (w > IMG_WIDTH_LIMIT || h > IMG_HEIGHT_LIMIT) { this.$message.error( "png圖片寬高不得超過(guò) " + IMG_WIDTH_LIMIT + "和" + IMG_HEIGHT_LIMIT ); return false; } } return ispng; }
附:js已知文件路徑,通用獲取文件名、后綴、類(lèi)型
代碼參考
// 選擇文件后返回 { resultData: '/storage/emulated/0/DCIM/Camera/IMG_20170703_133717.jpg' } var path ='/storage/emulated/0/DCIM/Camera/IMG_20170703_133717.jpg' ; var fileName = common.getFileNameByPath(path); // .jpg console.log("文件名="+fileName); var fileType=common.getFileTypeByPath(path); // jpg console.log("文件類(lèi)型="+fileType); var fileExtension=common.getFileExtensionByPath(path); // .jpg console.log("文件后綴="+fileExtension);
核心代碼
/** * 作者: 丸子 * 描述: 自定義工具 */ 'use strict'; window.common = window.common || (function(exports) { /* * 已知文件路徑,獲取文件名xxx.doc */ exports.getFileNameByPath = function(path) { var index = path.lastIndexOf("/"); // lastIndexOf("/") 找到最后一個(gè) / 的位置 var fileName = path.substr(index + 1); // substr() 截取剩余的字符,即得文件名xxx.doc return fileName; }; /* * 已知文件路徑,獲取文件類(lèi)型doc */ exports.getFileTypeByPath = function(path) { var index = path.lastIndexOf("."); // lastIndexOf("/") 找到最后一個(gè) / 的位置 var fileType = path.substr(index + 1); // substr() 截取剩余的字符,即文件名doc return fileType; }; /* * 已知文件路徑,獲取文件后綴.doc */ exports.getFileExtensionByPath = function(path) { var index1 = path.lastIndexOf("."); // lastIndexOf("/") 找到最后一個(gè) / 的位置 var index2 = path.length; var fileExtension = path.substr(index1, index2); // substr() 截取剩余的字符,即文件名.doc return fileExtension; }; return exports; })({});
總結(jié)
到此這篇關(guān)于JavaScript判斷文件類(lèi)型三種方法的文章就介紹到這了,更多相關(guān)js判斷文件類(lèi)型內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
javascript實(shí)現(xiàn)網(wǎng)站加入收藏功能
這篇文章主要介紹了javascript實(shí)現(xiàn)網(wǎng)站加入收藏功能的相關(guān)資料,需要的朋友可以參考下2015-12-12javascript特殊文本輸入框網(wǎng)頁(yè)特效
這篇文章主要為大家詳細(xì)介紹了javascript特殊文本輸入框網(wǎng)頁(yè)特效,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09JS實(shí)現(xiàn)購(gòu)物車(chē)特效
本文主要分享了用JavaScript實(shí)現(xiàn)購(gòu)物車(chē)特效的示例代碼。具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧2017-02-02詳解vscode中console.log的兩種快速寫(xiě)法
這篇文章主要介紹了vscode中console.log的兩種快速寫(xiě)法,每種方法通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-11-11javascript showModalDialog,open取得父窗口的方法
showModalDialog,open取得父窗口的代碼,需要的朋友可以參考下。2010-03-03Javascript中Promise的四種常用方法總結(jié)
這篇文章主要給大家總結(jié)介紹了關(guān)于Javascript中Promise的四種常用方法,分別是處理異步回調(diào)、多個(gè)異步函數(shù)同步處理、異步依賴(lài)異步回調(diào)和封裝統(tǒng)一的入口辦法或者錯(cuò)誤處理,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-07-07javascript實(shí)現(xiàn)點(diǎn)擊星星小游戲
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)點(diǎn)擊星星小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-12-12