การใช้งาน FormData ใน JavaScript
ในบทความก่อนหน้า เราได้เรียนรู้เกี่ยวกับการใช้ Fetch API เพื่อดึงข้อมูลจาก Server หรือ API อื่นๆ คราวนี้เราจะมาเรียนรู้เกี่ยวกับการใช้งาน FormData ซึ่งเป็น Object ที่ใช้ในการสร้างชุดข้อมูลที่สามารถส่งไปยัง Server ในรูปแบบ multipart/form-data ซึ่งมักใช้สำหรับการอัปโหลดไฟล์หรือส่งข้อมูลฟอร์มที่ซับซ้อน
FormData คืออะไร?
FormData เป็น Interface ที่ให้วิธีการสร้างชุดของ key/value pairs ที่เป็นตัวแทนของ fields ใน HTML form โดยสามารถใช้ในการส่งข้อมูลไปยัง Server ผ่าน HTTP request ได้ โดยเฉพาะอย่างยิ่งเมื่อต้องการส่งไฟล์หรือข้อมูลที่ไม่ได้อยู่ในรูปแบบ URL-encoded
การสร้าง FormData Object
การสร้าง FormData object นั้นง่ายมาก เพียงแค่ใช้ constructor ของ FormData:
const formData = new FormData();
คุณสามารถสร้าง FormData object จาก HTML form element ได้โดยตรง:
<form id="myForm">
<input type="text" name="username" value="JohnDoe">
<input type="file" name="profilePicture">
</form>
const formElement = document.getElementById('myForm');
const formData = new FormData(formElement);
การเพิ่ม Fields ลงใน FormData
หลังจากสร้าง FormData object แล้ว คุณสามารถเพิ่ม fields เข้าไปได้โดยใช้ method append():
formData.append('username', 'JohnDoe');
formData.append('email', 'john.doe@example.com');
// การเพิ่มไฟล์
const fileInput = document.querySelector('input[type="file"]');
const file = fileInput.files[0];
formData.append('profilePicture', file);
append() method รับสอง arguments: ชื่อของ field (key) และค่าของ field (value) สำหรับการเพิ่มไฟล์ คุณจะต้องดึง File object จาก <input type="file"> element ก่อน
การส่ง FormData ด้วย Fetch API
เมื่อคุณมี FormData object ที่มีข้อมูลครบถ้วนแล้ว คุณสามารถส่งมันไปยัง Server โดยใช้ Fetch API ได้:
const formData = new FormData();
formData.append('username', 'JohnDoe');
formData.append('email', 'john.doe@example.com');
fetch('/api/submit-form', {
method: 'POST',
body: formData
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
console.log('Success:', data);
})
.catch(error => {
console.error('Error:', error);
});
สิ่งที่สำคัญคือการกำหนด method เป็น 'POST' และกำหนด FormData object เป็น body ของ request Fetch API จะจัดการกับ Content-Type header ให้เป็น multipart/form-data โดยอัตโนมัติ
กรณีใช้งานจริง
การอัปโหลดไฟล์ภาพพร้อมข้อมูลเพิ่มเติม
สมมติว่าคุณต้องการสร้างฟอร์มสำหรับอัปโหลดภาพโปรไฟล์พร้อมกับชื่อผู้ใช้และอีเมล:
<form id="profileForm">
<label for="username">Username:</label>
<input type="text" id="username" name="username"><br><br>
<label for="email">Email:</label>
<input type="email" id="email" name="email"><br><br>
<label for="profilePicture">Profile Picture:</label>
<input type="file" id="profilePicture" name="profilePicture"><br><br>
<button type="submit">Submit</button>
</form>
const form = document.getElementById('profileForm');
form.addEventListener('submit', (event) => {
event.preventDefault(); // ป้องกันการ submit แบบ default
const formData = new FormData(form);
fetch('/api/upload-profile', {
method: 'POST',
body: formData
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
console.log('Success:', data);
})
.catch(error => {
console.error('Error:', error);
});
});
ในตัวอย่างนี้ เราใช้ addEventListener เพื่อดักจับ event submit ของ form จากนั้นเราสร้าง FormData object จาก form element และส่งไปยัง Server โดยใช้ Fetch API
ข้อผิดพลาดที่พบบ่อยและการแก้ไข
- Content-Type header ไม่ถูกต้อง: Fetch API จะจัดการ
Content-Typeheader ให้เป็นmultipart/form-dataโดยอัตโนมัติเมื่อbodyเป็นFormDataobject ไม่จำเป็นต้องกำหนดเอง - Server ไม่รองรับ
multipart/form-data: ตรวจสอบให้แน่ใจว่า Server ของคุณได้รับการตั้งค่าให้รองรับการรับข้อมูลในรูปแบบmultipart/form-data - การส่งข้อมูลขนาดใหญ่: หากคุณกำลังส่งไฟล์ขนาดใหญ่ อาจต้องมีการตั้งค่าเพิ่มเติมบน Server เพื่อรองรับการอัปโหลดไฟล์ขนาดใหญ่
- CORS error: หากคุณกำลังส่ง request ไปยัง domain อื่น ตรวจสอบให้แน่ใจว่า Server ปลายทางได้เปิดใช้งาน CORS (Cross-Origin Resource Sharing)
เคล็ดลับเพิ่มเติม
- การตรวจสอบขนาดไฟล์ก่อนอัปโหลด: ก่อนที่จะส่ง FormData ไปยัง Server คุณสามารถตรวจสอบขนาดของไฟล์ที่ผู้ใช้เลือกได้ เพื่อป้องกันการอัปโหลดไฟล์ที่มีขนาดใหญ่เกินไป
const fileInput = document.getElementById('profilePicture'); fileInput.addEventListener('change', () => { const file = fileInput.files[0]; if (file.size > 1024 * 1024 * 2) { // 2MB alert('File size exceeds 2MB'); fileInput.value = ''; // Clear the input } }); - การแสดง Progress Bar: ในการอัปโหลดไฟล์ขนาดใหญ่ การแสดง progress bar จะช่วยให้ผู้ใช้ทราบถึงสถานะการอัปโหลดได้
Fetch API ไม่มี built-in progress tracking โดยตรง แต่คุณสามารถใช้
XMLHttpRequestร่วมกับFormDataเพื่อให้ได้ progress tracking:const xhr = new XMLHttpRequest(); const formData = new FormData(form); xhr.upload.addEventListener('progress', (event) => { if (event.lengthComputable) { const percentComplete = (event.loaded / event.total) * 100; console.log(`Upload progress: ${percentComplete}%`); // อัปเดต progress bar ที่นี่ } }); xhr.open('POST', '/api/upload-profile'); xhr.send(formData);
สรุป
FormData เป็นเครื่องมือที่มีประโยชน์สำหรับการส่งข้อมูลในรูปแบบ multipart/form-data โดยเฉพาะอย่างยิ่งเมื่อคุณต้องการอัปโหลดไฟล์หรือส่งข้อมูลฟอร์มที่ซับซ้อน การใช้งานร่วมกับ Fetch API ทำให้การส่งข้อมูลไปยัง Server เป็นเรื่องง่ายและมีประสิทธิภาพ
ในบทความถัดไป เราจะเรียนรู้เกี่ยวกับการใช้งาน URL API ซึ่งเป็น API ที่ช่วยให้เราสามารถจัดการกับ URLs ได้อย่างง่ายดาย