ข้อมูลเบื้องต้นเกี่ยวกับ fetch()

fetch() ช่วยให้คุณส่งคำขอเครือข่ายได้คล้ายกับ XMLHttpRequest (XHR) ความแตกต่างหลักคือ Fetch API ใช้ Promise ซึ่งมี API ที่เรียบง่ายกว่าเพื่อช่วยหลีกเลี่ยงการเรียกกลับที่ซับซ้อนใน XMLHttpRequest API

Browser Support

  • Chrome: 42.
  • Edge: 14.
  • Firefox: 39.
  • Safari: 10.1.

Source

หากไม่เคยใช้พรอมิสมาก่อน โปรดดูข้อมูลเบื้องต้นเกี่ยวกับพรอมิสของ 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' })