ดึง API กับ XMLHttpRequest


163

ฉันรู้ว่า Fetch API ใช้Promises และทั้งคู่อนุญาตให้คุณทำคำขอ AJAX ไปยังเซิร์ฟเวอร์

ฉันได้อ่านแล้วว่า Fetch API มีคุณสมบัติพิเศษบางอย่างซึ่งไม่สามารถใช้ได้XMLHttpRequest(และใน Fetch API polyfill เนื่องจากมีพื้นฐานมาจากXHR)

API การดึงข้อมูลมีความสามารถพิเศษใดบ้าง


2
แม้ว่าฉันจำไม่ได้ในจุดนี้ แต่มีหนึ่งหรือสองอย่างที่คุณสามารถทำได้กับ XHR ที่คุณไม่สามารถทำได้ คุณบอกว่าคุณได้อ่านแล้วว่าการดึงข้อมูลมีความเป็นไปได้พิเศษบทความเหล่านั้นไม่ค่อยดีนักหากพวกเขาไม่ได้พูดในสิ่งที่พวกเขาต้องการ
Jaromanda X

2
พบสองสิ่งที่คุณไม่สามารถทำได้ด้วยการดึงข้อมูลที่คุณสามารถทำได้ด้วย XHR ... คุณไม่สามารถกำหนดค่าของคุณเองสำหรับคำขอหมดเวลาในการดึงข้อมูลและคุณไม่สามารถรับเหตุการณ์ความคืบหน้าได้
Jaromanda X

3
การดึงข้อมูลเป็นวิธีที่ง่ายกว่าในการทำสิ่งต่าง ๆ สำหรับ XMLHttpRequests เกือบทุกประเภท หากกรณีการใช้งานของคุณตรงกับสิ่งที่ Fetch ทำอยู่ให้ใช้มัน เมื่อคุณเข้าใจ XMLHttpRequest API น่าเกลียดสำหรับสิ่งที่คนส่วนใหญ่ใช้ Fetch เป็นความพยายามในการนำเสนอวิธีที่สะอาดกว่าในการทำสิ่งต่าง ๆ ที่ไม่ต้องการไลบรารีที่ล้อมรอบ XMLHttpRequest เพื่อให้เป็นที่พอใจ
jfriend00

1
มีการสนับสนุนอย่างแท้จริงในเบราว์เซอร์ ( caniuse.com/#search=fetch ) ดังนั้นจึงมี polifill สำหรับมันgithub.com/github/fetchซึ่งทำงานได้เหนือ xhr
ilyabasiuk

4
@Marco - วิธีที่คุณไม่สามารถพูดได้ว่าfetch(url).then(function(data) (...));ไม่ง่ายกว่าที่XMLHttpRequestจะใช้ในการทำสิ่งเดียวกันได้อย่างไร มันอาจมีคุณสมบัติอื่น ๆ อีกมากมาย แต่ geez แน่นอนว่าใช้ง่ายกว่าสำหรับสิ่งทั่วไป มันเป็น API ที่ล้างแล้ว
jfriend00

คำตอบ:


120

มีบางสิ่งที่คุณสามารถทำได้ด้วยการดึงข้อมูลและไม่ใช่กับ XHR:

  • คุณสามารถใช้ Cache API กับวัตถุที่ร้องขอและตอบสนอง
  • คุณสามารถดำเนินการno-corsตามคำขอรับการตอบสนองจากเซิร์ฟเวอร์ที่ไม่ได้ใช้ CORS คุณไม่สามารถเข้าถึงเนื้อหาการตอบสนองโดยตรงจาก JavaScript แต่คุณสามารถใช้กับ API อื่น ๆ (เช่น Cache API)
  • สตรีมการตอบกลับ (ด้วย XHR การตอบสนองทั้งหมดจะถูกบัฟเฟอร์ในหน่วยความจำด้วยการดึงข้อมูลคุณจะสามารถเข้าถึงสตรีมระดับต่ำ) ยังไม่พร้อมใช้งานในเบราว์เซอร์ทั้งหมด แต่จะใช้ในไม่ช้า

มีสองสิ่งที่คุณสามารถทำกับ XHR ที่คุณยังไม่สามารถทำได้ แต่พวกมันจะพร้อมใช้งานไม่ช้าก็เร็ว (อ่านย่อหน้า "การปรับปรุงในอนาคต" ที่นี่: https: //hacks.mozilla .org / 2015/03 / this-api-is-so-fetching / ):

  • ยกเลิกคำขอ (ตอนนี้ใช้งานได้ใน Firefox และ Edge ตามที่ @sideshowbarker อธิบายในความคิดเห็นของเขา)
  • รายงานความคืบหน้า

บทความนี้https://jakearchibald.com/2015/thats-so-fetch/มีคำอธิบายโดยละเอียดเพิ่มเติม


1
ข้อมูลจำเพาะสำหรับ Fetch API ตอนนี้มีให้สำหรับการยกเลิก สนับสนุนได้ส่งเพื่อให้ห่างไกลใน Firefox 57 และขอบ 16. สาธิต: fetch-abort-demo-edge.glitch.me , mdn.github.io/dom-examples/abort-api และมีเปิด Chrome และ Webkit ข้อบกพร่องคุณลักษณะbugs.chromium.org/p/chromium/issues/detail?id=750599 , bugs.webkit.org/show_bug.cgi?id=174980 วิธีการ: developers.google.com/web/updates/2017/09/abortable-fetch , developer.mozilla.org/en-US/docs/Web/API/AbortSignal#Examples และตัวอย่างในคำตอบของ Stack Overflow ที่stackoverflow.com/a/47250621/441757
sideshowbarker

1
ข้อแตกต่างอีกประการคือfetchคำขอไม่สามารถเล่นซ้ำได้บนเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์
Parziphal

และจากประสบการณ์ของฉันfetchสามารถขอไฟล์ได้ แต่ XHR ไม่สามารถทำได้
D. Pardal

64

นำมา

  • ไม่มีวิธีการสร้างขึ้นเพื่อใช้เอกสาร
  • ไม่มีวิธีการตั้งค่าหมดเวลาเลย
  • ไม่สามารถแทนที่ส่วนหัวการตอบกลับประเภทเนื้อหา
  • หากส่วนหัวการตอบสนองความยาวเนื้อหามีอยู่แต่ไม่ปรากฏความยาวทั้งหมดของเนื้อหาจะไม่เป็นที่รู้จักในระหว่างการสตรีม
  • จะเรียกใช้ตัวจัดการการยกเลิกของสัญญาณแม้ว่าคำขอจะเสร็จสมบูรณ์
  • ไม่มีความคืบหน้าในการอัปโหลด (รองรับReadableStreamอินสแตนซ์เนื่องจากยังไม่ได้รับคำขอ)

XHR

  • ไม่มีทางที่จะไม่ส่งคุกกี้ (นอกเหนือจากการใช้ธงที่ไม่ได้มาตรฐานmozAnonหรือคอนAnonXMLHttpRequestสตรัคเตอร์)
  • ไม่สามารถคืนFormDataอินสแตนซ์
  • ไม่ได้เทียบเท่ากับfetch's no-corsโหมด
  • ติดตามการเปลี่ยนเส้นทางเสมอ

13
fetchยังขาดความคืบหน้า ด้วย XHR คุณสามารถติดตามความคืบหน้ากับprogressเหตุการณ์ได้
rzr

1
"ไม่สามารถแทนที่ส่วนหัวประเภทเนื้อหาของการตอบสนอง" ... นี่เป็นเพียงความคิดที่ดีที่จะเริ่มต้นด้วย 'ประเภทเนื้อหากำหนดสิ่งที่จะถูกส่งคืนและ BACKEND ควรกำหนดให้ส่วนหน้า ในความเป็นจริงประเภทเนื้อหาควรเป็น 'ONLY HEADER' สำหรับประเภทเพราะสิ่งที่ร้องขอคือสิ่งที่ควรส่งคืน หากคุณต้องการบริการที่แตกต่างจากโดเมนย่อยพิเศษหรือบางอย่างเพื่อให้คุณสามารถจัดการฟังก์ชันการทำงานที่แยกต่างหาก คุณกำลังพยายามบังคับ 1% ให้ลด 99% ของคอทุกคน
Orubel

@Knu yep และตอนนี้เรามีความก้าวหน้ามากขึ้นและเราสามารถแก้ปัญหา 90% โดยอัตโนมัติได้อย่างง่ายดาย
Orubel

1
@rzr Response#bodyไม่ว่าคุณมี
Knu

9

คำตอบข้างต้นเป็นสิ่งที่ดีและให้ข้อมูลเชิงลึกที่ดี แต่ฉันแบ่งปันความคิดเห็นแบบเดียวกับที่แชร์ในรายการบล็อกนักพัฒนาของ Googleนี้ซึ่งความแตกต่างหลัก (จากมุมมองที่ใช้งานได้จริง) คือความสะดวกสบายของสัญญาในตัวfetch

แทนที่จะต้องเขียนโค้ดแบบนี้

function reqListener() {
    var data = JSON.parse(this.responseText);
}

function reqError(err) { ... }

var oReq = new XMLHttpRequest();
oReq.onload = reqListener;
oReq.onerror = reqError;
oReq.open('get', './api/some.json', true);
oReq.send();

เราสามารถทำความสะอาดและเขียนสิ่งที่กระชับและอ่านได้ง่ายขึ้นด้วยคำสัญญาและไวยากรณ์ที่ทันสมัย

fetch('./api/some.json')
    .then((response) => {
        response.json().then((data) => { 
            ... 
        });
    })
    .catch((err) => { ... });

8
@TheOpti คุณสามารถรองรับการดึงข้อมูลพื้นฐานลงใน IE 11 ได้คุณสามารถปล่อย IE11 เป็นเบราว์เซอร์ที่รองรับในหลายโครงการเช่นในฐานผู้ใช้จำนวนมากการใช้งาน IE 11 ต่ำกว่า 1%
Devon Holcombe
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.