File.type Property คืออะไร?
File.type เป็น property ของ File object (จาก <input type="file"> หรือ Drag & Drop) ที่คืนค่า MIME Type ของไฟล์ เช่น image/jpeg, application/pdf, text/plain
- คืนค่าเป็น string (เช่น
"image/png")
- ถ้าไม่สามารถระบุได้ จะคืนค่า
"" (empty string)
- ขึ้นอยู่กับ file extension และ content sniffing ของเบราว์เซอร์
- Read-only property
ตัวอย่างโค้ดครบถ้วน
<!DOCTYPE html>
<html lang="th">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>File.type Demo</title>
<style>
body { font-family: 'Segoe UI', sans-serif; padding: 20px; max-width: 700px; margin: 0 auto; }
.drop-zone { border: 3px dashed #7e32d4; border-radius: 12px; padding: 40px; text-align: center; margin: 20px 0; transition: all 0.2s; cursor: pointer; }
.drop-zone.drag-over { border-color: #4CAF50; background: #e8f5e9; }
.drop-zone input { display: none; }
.file-info { background: #f5f5f5; padding: 20px; border-radius: 8px; margin-top: 20px; }
.file-info h3 { margin-top: 0; color: #333; }
.info-row { display: flex; justify-content: space-between; padding: 8px 0; border-bottom: 1px solid #eee; }
.info-row:last-child { border-bottom: none; }
.label { color: #666; font-weight: 500; }
.value { font-family: monospace; color: #333; word-break: break-all; }
.mime-badge { display: inline-block; background: #7e32d4; color: white; padding: 4px 12px; border-radius: 20px; font-size: 14px; font-weight: bold; }
.warning { color: #f44336; font-size: 14px; margin-top: 10px; }
</style>
</head>
<body>
<h1>ตรวจสอบประเภทไฟล์ (File.type / MIME Type)</h1>
<p>ลากไฟล์วางที่นี่ หรือคลิกเพื่อเลือกไฟล์</p>
<div class="drop-zone" id="dropZone">
<input type="file" id="fileInput" multiple />
<div>📁 ลากไฟล์มาวางที่นี่ หรือคลิกเพื่อเลือก</div>
<small>รองรับหลายไฟล์พร้อมกัน</small>
</div>
<div class="file-info" id="fileInfo" style="display:none">
<h3>ข้อมูลไฟล์</div>
<div id="fileList"></div>
</div>
<script>
const dropZone = document.getElementById('dropZone');
const fileInput = document.getElementById('fileInput');
const fileInfo = document.getElementById('fileInfo');
const fileList = document.getElementById('fileList');
// Click to open file dialog
dropZone.addEventListener('click', () => fileInput.click());
// Drag & Drop
dropZone.addEventListener('dragover', (e) => {
e.preventDefault();
dropZone.classList.add('drag-over');
});
dropZone.addEventListener('dragleave', () => {
dropZone.classList.remove('drag-over');
});
dropZone.addEventListener('drop', (e) => {
e.preventDefault();
dropZone.classList.remove('drag-over');
handleFiles(e.dataTransfer.files);
});
// File input change
fileInput.addEventListener('change', (e) => {
handleFiles(e.target.files);
});
function handleFiles(files) {
if (!files.length) return;
fileInfo.style.display = 'block';
fileList.innerHTML = '';
Array.from(files).forEach((file, index) => {
const mimeType = file.type || 'ไม่สามารถระบุได้ (unknown)';
const isUnknown = !file.type;
const div = document.createElement('div');
div.style.marginBottom = '20px';
div.style.padding = '15px';
div.style.background = 'white';
div.style.borderRadius = '8px';
div.style.boxShadow = '0 2px 4px rgba(0,0,0,0.1)';
div.innerHTML = `
ไฟล์ #${index + 1}
ชื่อไฟล์:
${escapeHtml(file.name)}
ประเภท (MIME):
${escapeHtml(mimeType)}
ขนาด:
${formatFileSize(file.size)}
Last Modified:
${new Date(file.lastModified).toLocaleString('th-TH')}
${isUnknown ? '⚠️ ไม่สามารถระบุ MIME type ได้ - อาจเป็นไฟล์ที่ไม่มี extension หรือเบราว์เซอร์ไม่รู้จัก
' : ''}
`;
fileList.appendChild(div);
});
}
function formatFileSize(bytes) {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}
function escapeHtml(text) {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}
</script>
</body>
</html>
MIME Types ที่พบบ่อย
| Category | MIME Type | Extension |
| Images | image/jpeg, image/png, image/gif, image/webp, image/svg+xml | .jpg, .png, .gif, .webp, .svg |
| Documents | application/pdf, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document | .pdf, .doc, .docx |
| Spreadsheets | application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet | .xls, .xlsx |
| Text | text/plain, text/csv, text/html, text/css, application/json | .txt, .csv, .html, .css, .json |
| Archives | application/zip, application/x-rar-compressed, application/x-7z-compressed | .zip, .rar, .7z |
| Audio | audio/mpeg, audio/wav, audio/ogg, audio/mp4 | .mp3, .wav, .ogg, .m4a |
| Video | video/mp4, video/webm, video/quicktime, video/x-msvideo | .mp4, .webm, .mov, .avi |
การ Validate ไฟล์ฝั่ง Client (Client-side Validation)
const ALLOWED_TYPES = ['image/jpeg', 'image/png', 'image/webp', 'application/pdf'];
const MAX_SIZE = 5 * 1024 * 1024; // 5MB
function validateFile(file) {
const errors = [];
if (!ALLOWED_TYPES.includes(file.type)) {
errors.push(`ประเภทไฟล์ไม่รองรับ: ${file.type || 'unknown'}`);
}
if (file.size > MAX_SIZE) {
errors.push(`ไฟล์ใหญ่เกินไป: ${formatFileSize(file.size)} (สูงสุด 5MB)`);
}
return errors;
}
// ใช้งาน
fileInput.addEventListener('change', (e) => {
const file = e.target.files[0];
const errors = validateFile(file);
if (errors.length > 0) {
alert(errors.join('\n'));
e.target.value = ''; // clear input
return;
}
// proses upload...
});
⚠️ ข้อจำกัดสำคัญ: ไม่เชื่อถือได้ 100%
- File.type ขึ้นอยู่กับ Extension - เปลี่ยนชื่อไฟล์ .exe เป็น .jpg → type จะเป็น image/jpeg
- Content Sniffing - เบราว์เซอร์อ่านไบต์แรกๆ (Magic Numbers) แต่ไม่ครอบคลุมทุก format
- ต้อง Validate ฝั่ง Server เสมอ - ตรวจสอบ Magic Numbers, ใช้ไลบรารีเช่น
file-type (Node.js) หรือ python-magic
Magic Numbers (File Signatures) ตัวอย่าง
| Format | Magic Bytes (Hex) | ASCII |
| JPEG | FF D8 FF | ÿØÿ |
| PNG | 89 50 4E 47 0D 0A 1A 0A | ‰PNG... |
| PDF | 25 50 44 46 | %PDF |
| ZIP | 50 4B 03 04 | PK.. |
| MP4 | 00 00 00 18 66 74 79 70 | ....ftyp |