ข้อ จำกัด ใดที่ใช้กับการตอบสนองแบบทึบแสง?


89

การตอบสนองแบบทึบถูกกำหนดให้เป็นส่วนหนึ่งของFetch APIและแสดงถึงผลลัพธ์ของคำขอที่ส่งไปยังต้นทางระยะไกลเมื่อไม่ได้เปิดใช้งานCORS

ข้อ จำกัด ในทางปฏิบัติและ "gotcha" มีอะไรบ้างเกี่ยวกับวิธีการใช้การตอบกลับแบบทึบทั้งจาก JavaScript และเป็นทรัพยากรบนหน้าเว็บ

คำตอบ:


127

การเข้าถึงส่วนหัว / เนื้อหาของการตอบสนองแบบทึบ

ข้อ จำกัด ตรงไปตรงมามากที่สุดทั่วตอบสนองทึบแสงคือการที่คุณไม่สามารถได้รับข้อมูลกลับมามีความหมายจากส่วนใหญ่ของคุณสมบัติของResponseชั้นเหมือนheadersหรือโทรต่าง ๆวิธีการที่ทำขึ้นในBodyอินเตอร์เฟซที่เหมือนหรือjson() text()สิ่งนี้สอดคล้องกับลักษณะของกล่องดำของการตอบสนองแบบทึบแสง

การใช้การตอบสนองแบบทึบเป็นแหล่งข้อมูลบนเพจ

การตอบกลับแบบทึบสามารถใช้เป็นทรัพยากรบนหน้าเว็บเมื่อใดก็ตามที่เบราว์เซอร์อนุญาตให้ใช้ทรัพยากรข้ามแหล่งกำเนิดที่ไม่ใช่ CORS ต่อไปนี้เป็นองค์ประกอบย่อยที่ทรัพยากรข้ามแหล่งกำเนิดที่ไม่ใช่ CORS และสำหรับการตอบสนองแบบทึบนั้นถูกต้องซึ่งดัดแปลงมาจากเอกสารประกอบของ Mozilla Developer Network :

  • <script>
  • <link rel="stylesheet">
  • <img>, <video>และ<audio>
  • <object> และ <embed>
  • <iframe>

กรณีการใช้งานที่โดดเด่นที่การตอบสนองทึบแสงมีความไม่ถูกต้องสำหรับทรัพยากรอักษร

โดยทั่วไปในการพิจารณาว่าคุณสามารถใช้การตอบกลับแบบทึบเป็นทรัพยากรประเภทใดประเภทหนึ่งบนหน้าได้หรือไม่ให้ตรวจสอบข้อกำหนดที่เกี่ยวข้อง ตัวอย่างเช่นข้อกำหนด HTML อธิบายว่าการตอบสนองข้ามจุดเริ่มต้นที่ไม่ใช่ CORS (เช่นทึบแสง) สามารถใช้กับ<script>องค์ประกอบได้แม้ว่าจะมีข้อ จำกัด บางประการในการป้องกันข้อมูลข้อผิดพลาดรั่วไหล

การตอบสนองแบบทึบและ API การจัดเก็บแคช

หนึ่ง "gotcha" ที่นักพัฒนาอาจจะเป็นกับการตอบสนองขุ่นเกี่ยวข้องกับการใช้พวกเขาด้วยการจัดเก็บแคช API ข้อมูลภูมิหลังสองส่วนมีความเกี่ยวข้อง:

  • statusทรัพย์สินของการตอบสนองที่ทึบแสงเป็นที่ตั้งเสมอ0โดยไม่คำนึงว่าการร้องขอเดิมประสบความสำเร็จหรือล้มเหลว
  • การจัดเก็บแคชของ API add()/ addAll()วิธีการทั้งสองจะปฏิเสธถ้าการตอบสนองที่เกิดจากการใด ๆ ของการร้องขอมีรหัสสถานะที่ไม่ได้อยู่ในช่วง 2XX

จากสองจุดดังกล่าวเป็นไปตามที่ว่าหากคำขอที่ดำเนินการเป็นส่วนหนึ่งของadd()/ addAll()call ส่งผลให้เกิดการตอบสนองแบบทึบจะไม่สามารถเพิ่มลงในแคชได้

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

const request = new Request('https://third-party-no-cors.com/', {mode: 'no-cors'});
// Assume `cache` is an open instance of the Cache class.
fetch(request).then(response => cache.put(request, response));

การตอบสนองแบบทึบและ navigator.storage API

เพื่อที่จะหลีกเลี่ยงการรั่วไหลของข้อมูลข้ามโดเมนมีช่องว่างอย่างมีนัยสำคัญเพิ่มขนาดของการตอบสนองที่ทึบแสงที่ใช้สำหรับการคำนวณ จำกัด โควต้าการจัดเก็บข้อมูล (เช่นไม่ว่าจะเป็นQuotaExceededข้อยกเว้นจะถูกโยนทิ้ง) และรายงานโดยAPInavigator.storage

รายละเอียดของการขยายนี้แตกต่างจากเบราว์เซอร์เบราว์เซอร์ แต่สำหรับ Google Chrome, ที่นี้หมายถึงว่าขั้นต่ำขนาดใด ๆ ที่เดียวที่เก็บไว้ชั่วคราวก่อตอบสนองทึบแสงเพื่อการใช้งานที่จัดเก็บข้อมูลโดยรวมเป็นประมาณ 7 เมกะไบต์ คุณควรคำนึงถึงสิ่งนี้ในการกำหนดจำนวนการตอบสนองแบบทึบที่คุณต้องการแคชเนื่องจากคุณอาจเกินขีด จำกัด โควต้าพื้นที่เก็บข้อมูลได้เร็วกว่าที่คุณคาดไว้โดยพิจารณาจากขนาดจริงของทรัพยากรทึบแสง


1
ไม่ได้ใช้พื้นที่ในพื้นที่จัดเก็บข้อมูลจริงของอุปกรณ์ เป็นเพียงค่าที่ก่อให้เกิดการคำนวณโควต้า
Jeff Posnick

1
คำตอบของคุณยังระบุไว้ในคู่มือ Workbox ที่นี่: developers.google.com/web/tools/workbox/guides/…
Dima Slivin

14
จริง แต่ฉันเขียนคู่มือ Workbox :-)
Jeff Posnick

1
นั่นทำให้การใช้ Image CDN ร่วมกับแคชประเภทนี้เป็นการออกแบบที่ไม่ดีหรือไม่? (เสียพื้นที่ที่จัดสรร) เป็นไปได้ไหมที่จะแคชไฟล์ที่ดึงมาจากโดเมนหลักของเราและแสดงด้วยลิงค์ CDN (คีย์) ตัวอย่างเช่นฉันขอเครือข่ายไปที่cdn.x.com/test.jpgและขอแคชไปที่โดเมนหลักwww.x.com/test.jpgได้ไหม
cglacet

1
ฉันพบกลอุบายเกี่ยวกับปัญหานี้ฉันไม่รู้ว่านั่นเป็นวิธีแก้ปัญหาที่ดีหรือไม่ แต่โดยพื้นฐานแล้วฉันทำให้พนักงานบริการแกล้งทำเป็นว่าเป็น CDN ฉันเพิ่ม URL สัมพัทธ์ของโดเมนในแคช (เช่น/test.jpgจากนั้นสำหรับคำขอดึงข้อมูลแต่ละครั้งที่cdn.x.com/test.jpgฉันแก้ไข URL ด้วยโดเมนต้นทาง (URL กลายเป็นwww.x.com/test.jpg) ฉันใช้สิ่งนี้: const cacheUrl = (url.hostname == 'cdn.x.com')? new URL(event.target.location.origin + url.pathname): url;จากนั้นฉันขอแคชด้วย url ใหม่นี้caches.match(cacheUrl)ซึ่งดูเหมือนว่า ทำงานได้ดีอย่างไรก็ตามในแนวทางนี้หรือไม่
cglacet
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.