fetch()
ช่วยให้คุณส่งคำขอเครือข่ายได้คล้ายกับ XMLHttpRequest (XHR)
ความแตกต่างหลักๆ คือ Fetch API ใช้ Promises ซึ่งมี
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
เหล่านี้แสดงว่าแหล่งข้อมูลมาจากไหนและคุณสามารถใช้เพื่อ
กำหนดวิธีจัดการออบเจ็กต์การตอบกลับ
เมื่อเบราว์เซอร์ขอทรัพยากรจากต้นทางเดียวกัน การตอบกลับจะมีแอตทริบิวต์
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 เข้าด้วยกัน สําหรับ fetch()
ตัวเลือกนี้จะช่วยให้คุณแชร์ตรรกะในคําขอดึงข้อมูลได้
หากกำลังทำงานกับ JSON API คุณจะต้องตรวจสอบสถานะและแยกวิเคราะห์ JSON สำหรับแต่ละคำตอบ คุณสามารถลดความซับซ้อนของโค้ดได้โดยกำหนดสถานะและ การแยกวิเคราะห์ JSON ในฟังก์ชันแยกต่างหากซึ่งจะแสดงผลสัญญาและใช้การดึงข้อมูล จัดการเฉพาะข้อมูลสุดท้ายและกรณีข้อผิดพลาด
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'
})