Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> JavaScript

ตรวจสอบขนาดไฟล์ (Validate File Size) ก่อนอัปโหลดใน JavaScript

การตรวจสอบขนาดไฟล์ฝั่ง Client (Client-side Validation) ช่วยประหยัด Bandwidth และให้ UX ดีกว่า แต่ ต้องตรวจสอบฝั่ง Server อีกครั้งเสมอ (Client-side แก้ไขได้)

ตัวอย่าง: ตรวจสอบขนาดไฟล์ก่อนอัปโหลด

<!DOCTYPE html>
<html lang="th">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Validate File Size</title>
    <style>
        body { font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif; padding: 20px; }
        .result { font-size: 18px; font-weight: 500; color: blueviolet; margin: 10px 0; padding: 15px; border-radius: 4px; }
        .success { background: #d4edda; color: #155724; border: 1px solid #c3e6cb; }
        .error { background: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; }
        .warning { background: #fff3cd; color: #856404; border: 1px solid #ffeeba; }
        input[type="file"] { margin: 10px 0; }
    </style>
</head>
<body>
    <h1>ตรวจสอบขนาดไฟล์ก่อนอัปโหลด</h1>
    <input type="file" id="fileInput" onchange="validateFile()">
    <div class="result" id="result"></div>
    <h3>เลือกไฟล์เพื่อตรวจสอบขนาด (จำกัด 4MB)</h3>

    <script>
        const fileInput = document.getElementById("fileInput");
        const result = document.getElementById("result");
        const MAX_SIZE_MB = 4;
        const MAX_SIZE_BYTES = MAX_SIZE_MB * 1024 * 1024;
        
        function validateFile() {
            result.innerHTML = "";
            result.className = "result";
            
            if (fileInput.files.length === 0) {
                result.textContent = "ไม่ได้เลือกไฟล์";
                result.classList.add("warning");
                return;
            }
            
            const file = fileInput.files[0];
            const fileSize = file.size; // Bytes
            const fileSizeMB = (fileSize / (1024 * 1024)).toFixed(2);
            
            result.innerHTML = `
                ชื่อไฟล์: ${escapeHtml(file.name)}
ขนาด: ${fileSize} bytes (${fileSizeMB} MB)
ประเภท: ${file.type || "Unknown"}
แก้ไขล่าสุด: ${new Date(file.lastModified).toLocaleString("th-TH")} `; if (fileSize > MAX_SIZE_BYTES) { result.innerHTML += `
❌ ไฟล์ใหญ่เกินไป! สูงสุด ${MAX_SIZE_MB} MB`; result.classList.add("error"); } else { result.innerHTML += `
✅ ผ่านการตรวจสอบ - พร้อมอัปโหลด`; result.classList.add("success"); } } function escapeHtml(text) { const div = document.createElement("div"); div.textContent = text; return div.innerHTML; } </script> </body> </html>

ผลลัพธ์

เลือกไฟล์ ≤ 4MB → ✅ สีเขียว "พร้อมอัปโหลด"
เลือกไฟล์ > 4MB → ❌ สีแดง "ไฟล์ใหญ่เกินไป!"

ขยาย: ตรวจสอบหลายไฟล์พร้อมกัน

<input type="file" id="multiFile" multiple>

<script>
    document.getElementById("multiFile").addEventListener("change", (e) => {
        const files = Array.from(e.target.files);
        const MAX_SIZE = 5 * 1024 * 1024; // 5MB
        const errors = [];
        
        files.forEach(file => {
            if (file.size > MAX_SIZE) {
                errors.push(`${file.name} (${(file.size/1024/1024).toFixed(2)} MB) เกิน ${MAX_SIZE/1024/1024} MB`);
            }
        });
        
        if (errors.length > 0) {
            alert("ไฟล์ต่อไปนี้เกินขนาด:\n" + errors.join("\n"));
            e.target.value = ""; // Clear selection
        }
    });
</script>

ขยาย: ตรวจสอบประเภทไฟล์ (File Type Validation)

const ALLOWED_TYPES = [
    "image/jpeg", "image/png", "image/gif", "image/webp",
    "application/pdf",
    "text/plain"
];

function validateFileType(file) {
    // ตรวจสอบ MIME Type
    if (!ALLOWED_TYPES.includes(file.type)) {
        return { valid: false, reason: `ประเภทไฟล์ไม่รองรับ: ${file.type}` };
    }
    
    // ตรวจสอบ Extension (Fallback)
    const ext = file.name.split(".").pop().toLowerCase();
    const allowedExts = ["jpg", "jpeg", "png", "gif", "webp", "pdf", "txt"];
    if (!allowedExts.includes(ext)) {
        return { valid: false, reason: `นามสกุลไฟล์ไม่รองรับ: .${ext}` };
    }
    
    return { valid: true };
}

⚠️ ข้อจำกัดของ Client-side Validation

  • ผู้ใช้สามารถแก้ไข JavaScript / Bypass ได้ (DevTools)
  • MIME Type สามารถปลอมได้ (file.type มาจาก Extension ไม่ใช่เนื้อหาจริง)
  • ต้อง Validate ที่ Server เสมอ (Node.js, PHP, Python, Java, etc.)

Server-side Validation (Node.js + Multer Example)

const multer = require("multer");

const upload = multer({
    limits: { fileSize: 4 * 1024 * 1024 }, // 4MB
    fileFilter: (req, file, cb) => {
        const allowed = ["image/jpeg", "image/png", "application/pdf"];
        if (allowed.includes(file.mimetype)) {
            cb(null, true);
        } else {
            cb(new Error("Invalid file type"), false);
        }
    }
});

app.post("/upload", upload.single("file"), (req, res) => {
    // ไฟล์ผ่านการตรวจสอบแล้ว
    res.json({ success: true, filename: req.file.filename });
});