一、為什麼需要限制文件類型
在前後端交互的過程中,我們經常需要上傳和下載文件。但是文件類型有可能是惡意文件,例如:病毒、木馬等。限制文件類型可以避免惡意文件的上傳和下載,保證網站的安全。
二、前端限制文件類型的方式
前端根據不同瀏覽器的API,可以通過以下方式來限制文件類型:
1、設置文件類型的accept屬性
<input type="file" accept=".doc,.docx,.pdf,.jpg,.jpeg,.png" />
accept屬性控制文件選取對話框只彈出指定類型文件,但是用戶仍然可以通過修改文件擴展名來繞過驗證,所以需要在後端再次驗證文件類型。
2、使用FileReader對象讀取文件類型
const file = event.target.files[0];
const reader = new FileReader();
reader.onload = () => {
const result = reader.result;
const arr = new Uint8Array(result);
const header = [];
for (let i = 0; i < arr.length; i++) {
header.push(arr[i].toString(16));
}
const fileType = getFileType(header.join(''));
};
reader.readAsArrayBuffer(file);
function getFileType(head) {
switch (head) {
case '89504e47':
return 'image/png';
case '47494638':
return 'image/gif';
case '25504446':
return 'application/pdf';
default:
return 'unknown';
}
}
使用FileReader對象讀取文件,獲取文件的位元組流,根據位元組流的前幾位,判斷文件類型。但是這種方式只能讀取文件的前幾個位元組,可能存在誤判,需要後端再次驗證。
三、後端限制文件類型的方式
後端也需要對文件類型進行驗證,避免繞過前端驗證的惡意文件被上傳。
1、使用mime類型判斷文件類型
const fs = require('fs');
const fileType = require('file-type');
const file = fs.readFileSync('/path/to/file');
const mime = fileType(file).mime;
if (!/^(image\/|video\/|audio\/)/.test(mime)) {
console.log('文件類型錯誤');
}
使用file-type插件獲取文件的mime類型,根據mime類型判斷文件類型是否符合規定。缺點是文件沒有擴展名時無法判斷。
2、使用擴展名判斷文件類型
const path = require('path');
const extname = path.extname('/path/to/file');
if (!/^(.jpg|.jpeg|.png)$/i.test(extname)) {
console.log('文件類型錯誤');
}
通過文件的擴展名判斷文件類型是否符合規定。但是擴展名是可以被修改的,所以需要結合mime類型驗證。
四、總結
前後端都需要對文件類型進行驗證,可以通過accept屬性、FileReader對象、mime類型、擴展名等方式進行驗證。建議採用多種方式結合,提高驗證的準確性。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/190879.html