fetch()
ช่วยให้คุณส่งคำขอเครือข่ายได้คล้ายกับ XMLHttpRequest (XHR) ความแตกต่างหลักคือ Fetch API ใช้ Promise ซึ่งมี API ที่เรียบง่ายกว่าเพื่อช่วยหลีกเลี่ยงการเรียกกลับที่ซับซ้อนใน XMLHttpRequest API
หากไม่เคยใช้พรอมิสมาก่อน โปรดดูข้อมูลเบื้องต้นเกี่ยวกับพรอมิสของ JavaScript
คำขอดึงข้อมูลพื้นฐาน
ต่อไปนี้คือตัวอย่างการใช้งานกับ XMLHttpRequest
และ fetch
เราต้องการขอ URL รับการตอบกลับ และแยกวิเคราะห์เป็น JSON
XMLHttpRequest
XMLHttpRequest
ต้องมี Listener 2 ตัวเพื่อจัดการกรณีที่สำเร็จและกรณีที่เกิดข้อผิดพลาด รวมถึงการเรียกใช้ open()
และ send()
ตัวอย่างจากเอกสาร MDN
function reqListener () { const data = JSON.parse(this.responseText); console.log(data); } function reqError (err) { console.log('Fetch Error :-S', err); } const oReq = new XMLHttpRequest(); oReq.onload = reqListener; oReq.onerror = reqError; oReq.open('get', './api/some.json', true); oReq.send();
ดึงข้อมูล
คำขอดึงข้อมูลของเรามีลักษณะดังนี้
fetch('./api/some.json') .then(response => { if (response.status !== 200) { console.log(`Looks like there was a problem. Status Code: ${response.status}`); return; } // Examine the text in the response response.json().then(function(data) { console.log(data); }); }) .catch(err => { console.log('Fetch Error :-S', err); });
คำขอ fetch()
ต้องมีการเรียกใช้เพียงครั้งเดียวเพื่อทํางานแบบเดียวกับตัวอย่าง XHR ในการดำเนินการกับคำตอบ เราจะตรวจสอบก่อนว่าสถานะการตอบกลับคือ 200 จากนั้นจึงแยกวิเคราะห์คำตอบเป็น JSON การตอบกลับคําขอ fetch()
คือออบเจ็กต์ Stream ซึ่งหมายความว่าหลังจากเรียกใช้เมธอด json()
ระบบจะแสดงผล Promise สตรีมจะเกิดขึ้นแบบอะซิงโครนัส
ข้อมูลเมตาของคำตอบ
ตัวอย่างก่อนหน้านี้แสดงสถานะของออบเจ็กต์ Response และวิธีแยกวิเคราะห์การตอบกลับเป็น JSON วิธีจัดการข้อมูลเมตาอื่นๆ ที่คุณอาจต้องการเข้าถึง เช่น ส่วนหัวมีดังนี้
fetch('users.json').then(response => { console.log(response.headers.get('Content-Type')); console.log(response.headers.get('Date')); console.log(response.status); console.log(response.statusText); console.log(response.type); console.log(response.url); });
ประเภทการตอบกลับ
เมื่อเราส่งคำขอดึงข้อมูล ระบบจะใส่ response.type
ให้กับคำตอบ ซึ่งก็คือ "basic
", "cors
" หรือ "opaque
" types
เหล่านี้จะแสดงแหล่งที่มาของทรัพยากร และคุณใช้ types
เหล่านี้เพื่อกำหนดวิธีจัดการออบเจ็กต์คำตอบได้
เมื่อเบราว์เซอร์ขอทรัพยากรจากต้นทางเดียวกัน การตอบกลับจะมีประเภท basic
ที่มีข้อจำกัดเกี่ยวกับสิ่งที่คุณดูจากการตอบกลับได้
หากมีการส่งคําขอทรัพยากรในต้นทางอื่น และต้นทางนั้นแสดงส่วนหัว CORs ประเภทจะเป็น cors
cors
คำตอบจะคล้ายกับคำตอบ basic
แต่จำกัดส่วนหัวที่คุณดูได้ไว้ที่ Cache-Control
, Content-Language
, Content-Type
, Expires
, Last-Modified
และ Pragma
การตอบกลับ opaque
มาจากต้นทางอื่นที่ไม่ได้แสดงส่วนหัว CORS เมื่อใช้การตอบกลับแบบทึบ เราจะอ่านข้อมูลที่แสดงผลหรือดูสถานะคำขอไม่ได้ ซึ่งหมายความว่าคุณจะตรวจสอบไม่ได้ว่าคำขอสำเร็จหรือไม่
คุณสามารถกําหนดโหมดสําหรับคําขอดึงข้อมูลเพื่อให้มีเพียงคําขอบางประเภทเท่านั้นที่แก้ไขได้ โหมดที่คุณตั้งค่าได้มีดังนี้
same-origin
จะดำเนินการสําเร็จสําหรับคําขอชิ้นงานที่ต้นทางเดียวกันเท่านั้น และจะปฏิเสธคําขออื่นๆ ทั้งหมดcors
อนุญาตคําขอชิ้นงานที่ต้นทางเดียวกันและต้นทางอื่นๆ ที่แสดงผลส่วนหัว CORS ที่เหมาะสมcors-with-forced-preflight
จะทำการตรวจสอบก่อนเที่ยวบินก่อนที่จะส่งคำขอno-cors
มีไว้เพื่อส่งคำขอไปยังต้นทางอื่นๆ ที่ไม่มีส่วนหัว CORS และส่งผลให้มีการตอบกลับopaque
แต่ตามที่ระบุไว้ การดำเนินการนี้ยังไม่สามารถทำได้ในขอบเขตระดับหน้าต่างทั่วโลกในขณะนี้
หากต้องการกําหนดโหมด ให้เพิ่มออบเจ็กต์ตัวเลือกเป็นพารามิเตอร์ที่ 2 ในคําขอ fetch
แล้วกําหนดโหมดในออบเจ็กต์นั้น
fetch('http://some-site.com/cors-enabled/some.json', {mode: 'cors'}) .then(response => response.text()) .then(text => { console.log('Request successful', text); }) .catch(error => { log('Request failed', error) });
การต่อ Promise
หนึ่งในฟีเจอร์ที่ยอดเยี่ยมของ Promise คือความสามารถในการต่อเชื่อม Promise เข้าด้วยกัน สําหรับ fetch()
ตัวเลือกนี้จะช่วยให้คุณแชร์ตรรกะในคําขอดึงข้อมูลได้
หากใช้ JSON API คุณต้องตรวจสอบสถานะและแยกวิเคราะห์ JSON สำหรับการตอบกลับแต่ละรายการ คุณลดความซับซ้อนของโค้ดได้โดยกำหนดสถานะและการแยกวิเคราะห์ JSON ในฟังก์ชันแยกต่างหากซึ่งแสดงผล Promise และใช้คำขอการเรียกข้อมูลเพื่อจัดการเฉพาะข้อมูลสุดท้ายและกรณีข้อผิดพลาด
function status (response) { if (response.status >= 200 && response.status < 300) { return Promise.resolve(response) } else { return Promise.reject(new Error(response.statusText)) } } function json (response) { return response.json() } fetch('users.json') .then(status) .then(json) .then(data => { console.log('Request succeeded with JSON response', data); }).catch(error => { console.log('Request failed', error); });
ตัวอย่างนี้จะกำหนดฟังก์ชัน status
ที่ตรวจสอบ response.status
และแสดงผล Promise ที่สำเร็จรูปเป็น Promise.resolve()
หรือแสดงผล Promise ที่ปฏิเสธเป็น Promise.reject()
ซึ่งเป็นเมธอดแรกที่เรียกใช้ในเชน fetch()
หาก Promise ได้รับการแก้ไข สคริปต์จะเรียกใช้เมธอด json()
ซึ่งจะแสดงผล Promise รายการที่ 2 จากการเรียกใช้ response.json()
และสร้างออบเจ็กต์ที่มี JSON ที่แยกวิเคราะห์แล้ว หากแยกวิเคราะห์ไม่สำเร็จ ระบบจะปฏิเสธ Promise และคำสั่ง catch จะทำงาน
โครงสร้างนี้ช่วยให้คุณแชร์ตรรกะในคําขอดึงข้อมูลทั้งหมดได้ ทําให้ดูแลรักษา อ่าน และทดสอบโค้ดได้ง่ายขึ้น
คำขอ POST
บางครั้งเว็บแอปต้องเรียก API ด้วยเมธอด POST และใส่พารามิเตอร์บางอย่างในเนื้อหาของคําขอ โดยให้ตั้งค่าพารามิเตอร์ method
และ body
ในตัวเลือก fetch()
ดังนี้
fetch(url, { method: 'post', headers: { "Content-type": "application/x-www-form-urlencoded; charset=UTF-8" }, body: 'foo=bar&lorem=ipsum' }) .then(json) .then(data => { console.log('Request succeeded with JSON response', data); }) .catch(error => { console.log('Request failed', error); });
ส่งข้อมูลเข้าสู่ระบบด้วยคำขอดึงข้อมูล
หากต้องการส่งคำขอดึงข้อมูลโดยใช้ข้อมูลเข้าสู่ระบบ เช่น คุกกี้ ให้ตั้งค่าcredentials
ของคำขอเป็น "include"
fetch(url, { credentials: 'include' })