Fetch/XMLHttpRequest ใน JavaScript

Fetch/XMLHttpRequest ใน JavaScript

บทความนี้อธิบายเกี่ยวกับ Fetch/XMLHttpRequest ใน JavaScript

YouTube Video

javascript-html-fetch-xhr.html
  1<!DOCTYPE html>
  2<html lang="en">
  3<head>
  4  <meta charset="UTF-8">
  5  <title>JavaScript &amp; HTML</title>
  6  <style>
  7    * {
  8        box-sizing: border-box;
  9    }
 10
 11    body {
 12        margin: 0;
 13        padding: 1em;
 14        padding-bottom: 10em;
 15        font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
 16        background-color: #f7f9fc;
 17        color: #333;
 18        line-height: 1.6;
 19    }
 20
 21    .container {
 22        max-width: 800px;
 23        margin: 0 auto;
 24        padding: 1em;
 25        background-color: #ffffff;
 26        border: 1px solid #ccc;
 27        border-radius: 10px;
 28        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
 29    }
 30
 31    .container-flex {
 32        display: flex;
 33        flex-wrap: wrap;
 34        gap: 2em;
 35        max-width: 1000px;
 36        margin: 0 auto;
 37        padding: 1em;
 38        background-color: #ffffff;
 39        border: 1px solid #ccc;
 40        border-radius: 10px;
 41        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
 42    }
 43
 44    .left-column, .right-column {
 45        flex: 1 1 200px;
 46        min-width: 200px;
 47    }
 48
 49    h1, h2 {
 50        font-size: 1.2rem;
 51        color: #007bff;
 52        margin-top: 0.5em;
 53        margin-bottom: 0.5em;
 54        border-left: 5px solid #007bff;
 55        padding-left: 0.6em;
 56        background-color: #e9f2ff;
 57    }
 58
 59    button {
 60        display: block;
 61        margin: 1em auto;
 62        padding: 0.75em 1.5em;
 63        font-size: 1rem;
 64        background-color: #007bff;
 65        color: white;
 66        border: none;
 67        border-radius: 6px;
 68        cursor: pointer;
 69        transition: background-color 0.3s ease;
 70    }
 71
 72    button:hover {
 73        background-color: #0056b3;
 74    }
 75
 76    #output {
 77        margin-top: 1em;
 78        background-color: #1e1e1e;
 79        color: #0f0;
 80        padding: 1em;
 81        border-radius: 8px;
 82        min-height: 200px;
 83        font-family: Consolas, monospace;
 84        font-size: 0.95rem;
 85        overflow-y: auto;
 86        white-space: pre-wrap;
 87    }
 88
 89    .highlight {
 90        outline: 3px solid #ffc107; /* yellow border */
 91        background-color: #fff8e1;  /* soft yellow background */
 92        transition: background-color 0.3s ease, outline 0.3s ease;
 93    }
 94
 95    .active {
 96        background-color: #28a745; /* green background */
 97        color: #fff;
 98        box-shadow: 0 0 10px rgba(40, 167, 69, 0.5);
 99        transition: background-color 0.3s ease, box-shadow 0.3s ease;
100    }
101  </style>
102</head>
103<body>
104    <div class="container">
105        <h1>JavaScript Console</h1>
106        <button id="executeBtn">Execute</button>
107        <div id="output"></div>
108    </div>
109
110    <script>
111        // Override console.log to display messages in the #output element
112        (function () {
113            // Override console.log
114            const originalLog = console.log;
115            console.log = function (...args) {
116                originalLog.apply(console, args);
117                const message = document.createElement('div');
118                message.textContent = args.map(String).join(' ');
119                output.appendChild(message);
120            };
121
122            // Override console.error
123            const originalError = console.error;
124            console.error = function (...args) {
125                originalError.apply(console, args);
126                const message = document.createElement('div');
127                message.textContent = args.map(String).join(' ');
128                message.style.color = 'red'; // Color error messages red
129                output.appendChild(message);
130            };
131        })();
132
133        document.getElementById('executeBtn').addEventListener('click', () => {
134            // Prevent multiple loads
135            if (document.getElementById('externalScript')) return;
136
137            const script = document.createElement('script');
138            script.src = 'javascript-html-fetch-xhr.js';
139            script.id = 'externalScript';
140            //script.onload = () => console.log('javascript-html-fetch-xhr.js loaded and executed.');
141            //script.onerror = () => console.log('Failed to load javascript-html-fetch-xhr.js.');
142            document.body.appendChild(script);
143        });
144    </script>
145</body>
146</html>

Fetch/XMLHttpRequest ใน JavaScript

Fetch และ XMLHttpRequest (XHR) ใน JavaScript ใช้สำหรับส่งคำขอ HTTP และดึงข้อมูลจากเซิร์ฟเวอร์

Fetch API

Fetch API เป็นวิธีที่ทันสมัยสำหรับจัดการคำขอ HTTP ที่ออกแบบมาเป็นตัวแทนของ XHR เป็น API แบบอะซิงโครนัสที่อยู่บนพื้นฐานของ Promises ช่วยให้การจัดการคำขอสามารถทำได้ง่ายและยืดหยุ่นมากขึ้น

การใช้งาน

 1fetch('http://127.0.0.1:3000/example.json')
 2    .then((response) => {
 3        if (!response.ok) {
 4            throw new Error('HTTP error: ' + response.status);
 5        }
 6        return response.json();  // Parse the response as JSON
 7    })
 8    .then((data) => {
 9        console.log(data);  // Use the fetched data
10        console.log(JSON.stringify(data));
11    })
12    .catch((error) => {
13        console.error('An error occurred:', error);  // Error handling
14    });
  • โค้ดนี้ส่งคำขอ GET ไปยัง URL ที่ระบุโดยใช้ Fetch API ประมวลผลการตอบกลับเป็น JSON และแสดงผลลัพธ์หรือข้อความผิดพลาด

คุณสมบัติ

Fetch API มีคุณสมบัติดังต่อไปนี้:

  • ใช้ Promise สามารถจัดการการทำงานแบบอะซิงโครนัสด้วย Promise ทำให้โค้ดดูสะอาดและอ่านง่ายขึ้น
  • จัดการข้อผิดพลาดได้ง่าย สามารถจัดการข้อผิดพลาดได้อย่างง่ายดายโดยใช้บล็อก catch
  • แปลงข้อมูลด้วยเมธอด เช่น response.json() ข้อมูลที่ได้รับสามารถประมวลผลเป็นรูปแบบ JSON หรือข้อความได้อย่างง่ายดาย
  • รองรับ CORS Fetch ทำงานตามกฎของ Cross-Origin Resource Sharing (CORS)
  • กำหนดค่าคำขอได้อย่างยืดหยุ่น ไม่เพียงแค่ GET/POST เท่านั้น แต่สามารถกำหนด HTTP methods อื่นๆ เช่น PUT และ DELETE ได้อย่างง่ายดาย

ตัวอย่าง: คำขอแบบ POST

 1fetch('http://127.0.0.1:3000/example.json', {
 2        method: 'POST',
 3        headers: {
 4            'Content-Type': 'application/json'
 5        },
 6        body: JSON.stringify({ name: 'Alice', age: 25 })  // Send the request body as JSON
 7    })
 8    .then(response => response.json())
 9    .then(data => console.log(JSON.stringify(data)))
10    .catch(error => console.error('Error:', error));
  • โค้ดนี้ส่งคำขอ POST ที่มีข้อมูล JSON และรับรวมถึงแสดงผลลัพธ์จากเซิร์ฟเวอร์เป็น JSON

ข้อเสีย

Fetch API มีข้อเสียดังต่อไปนี้:

  • ความเข้ากันได้กับเบราว์เซอร์ เบราว์เซอร์รุ่นเก่า (โดยเฉพาะ IE11) ไม่รองรับ Fetch API
  • ควบคุมรายละเอียดได้ยาก เมื่อเทียบกับ XHR แล้ว ไม่เหมาะสำหรับการควบคุมในระดับต่ำ เช่น การจัดการอีเวนต์ความคืบหน้า

XMLHttpRequest(XHR)

XMLHttpRequest เป็น API ที่ถูกใช้มานานสำหรับจัดการคำขอ HTTP และถูกนำมาใช้อย่างแพร่หลายเป็นพื้นฐานสำหรับ AJAX (Asynchronous JavaScript and XML) ช่วยให้การสื่อสารแบบอะซิงโครนัสเป็นไปได้ ทำให้สามารถดึงข้อมูลจากเซิร์ฟเวอร์ได้โดยไม่ต้องโหลดหน้าใหม่ทั้งหน้า

การใช้งาน

 1const xhr = new XMLHttpRequest();
 2xhr.open('GET', 'http://127.0.0.1:3000/example.json', true);
 3xhr.onreadystatechange = function() {
 4    if (xhr.readyState === 4 && xhr.status === 200) {
 5        const data = JSON.parse(xhr.responseText);  // Parse the response as JSON
 6        console.log(data);  // Use the data
 7        console.log(JSON.stringify(data));
 8    }
 9};
10xhr.send();  // Send the request
  • โค้ดนี้ส่งคำขอ GET โดยใช้ XMLHttpRequest แปลงข้อมูลตอบกลับแบบ JSON และแสดงผลลัพธ์

คุณสมบัติ

XMLHttpRequest มีคุณสมบัติดังต่อไปนี้:

  • ใช้ Callback ใช้ฟังก์ชัน callback เช่น onreadystatechange เพื่อติดตามสถานะเสร็จสมบูรณ์หรือความคืบหน้าของคำขอ
  • ตรวจสอบรหัสสถานะและสถานะพร้อมใช้งาน สามารถตรวจสอบสถานะของคำขอได้โดยใช้ xhr.readyState และ xhr.status
  • เข้ากันได้กว้าง สามารถใช้งานได้แม้กับเบราว์เซอร์รุ่นเก่า
  • ตรวจสอบความคืบหน้าของคำขอ สามารถติดตามความคืบหน้าได้โดยใช้อีเวนต์ เช่น xhr.upload.onprogress

ตัวอย่าง: คำขอแบบ POST

 1const xhr = new XMLHttpRequest();
 2xhr.open('POST', 'http://127.0.0.1:3000/example.json', true);
 3xhr.setRequestHeader('Content-Type', 'application/json');
 4xhr.onreadystatechange = function() {
 5    if (xhr.readyState === 4 && xhr.status === 200) {
 6        const data = JSON.parse(xhr.responseText);
 7        console.log(data);
 8        console.log(JSON.stringify(data));
 9    }
10};
11xhr.send(JSON.stringify({ name: 'Alice', age: 25 }));  // Send the data
  • โค้ดนี้ส่งคำขอ POST พร้อมข้อมูล JSON โดยใช้ XMLHttpRequest รับและแสดงผลลัพธ์

ข้อเสีย

XMLHttpRequest มีข้อเสียดังต่อไปนี้:

  • ความซับซ้อนของโค้ด การจัดการอะซิงโครนัสด้วย callback functions อาจทำให้โค้ดซับซ้อน
  • ไม่รองรับ Promise โดยตรง เนื่องจากไม่รองรับ Promise โดยตรง การจัดการอะซิงโครนัสจึงอาจยืดยาวหรือซับซ้อนขึ้น

การเปรียบเทียบระหว่าง Fetch API และ XMLHttpRequest

คุณสมบัติ Fetch API XMLHttpRequest (XHR)
การประมวลผลแบบอะซิงโครนัส เรียบง่ายด้วย Promises ต้องใช้ฟังก์ชัน callback
การจัดการข้อผิดพลาด จัดการได้ง่ายด้วย .catch() ตรวจสอบสถานะ readyState
เหตุการณ์ความคืบหน้า ไม่รองรับ จัดการด้วย onprogress
การรองรับข้ามต้นกำเนิด (Cross-origin) รองรับ CORS โดยอัตโนมัติ รองรับ CORS
การรองรับเบราว์เซอร์ ไม่รองรับใน IE11 และรุ่นเก่า เข้ากันได้กับเบราว์เซอร์รุ่นเก่า
ความละเอียดในการควบคุม เรียบง่ายและใช้งานง่าย อนุญาตให้ควบคุมในระดับละเอียด

สรุป

  • Fetch API ให้การร้องขอ HTTP ที่เรียบง่ายและยืดหยุ่นโดยใช้ Promises และแนะนำให้ใช้ในเบราว์เซอร์สมัยใหม่

คุณสามารถติดตามบทความข้างต้นโดยใช้ Visual Studio Code บนช่อง YouTube ของเรา กรุณาตรวจสอบช่อง YouTube ด้วย

YouTube Video