คำอธิบาย
ใช้ chrome.mimeHandler API เพื่อจัดการสตรีมประเภท MIME ในส่วนขยายของบุคคลที่สาม
ความพร้อมใช้งาน
ไฟล์ Manifest
แนวคิดและการใช้งาน
ที่ผ่านมา ส่วนขยายของบุคคลที่สามที่จัดการเอกสารบางประเภท (เช่น โปรแกรมอ่าน PDF) อาศัยการสกัดกั้นคำขอเครือข่ายเพื่อตรวจจับการไปยังส่วนต่างๆ และเปลี่ยนเส้นทางผู้ใช้ไปยังหน้าส่วนขยาย การลงทะเบียนเป็นเครื่องจัดการ MIME จะช่วยหลีกเลี่ยงข้อจำกัดหลายประการของแนวทางดังกล่าว ดังนี้
- URL ต้นทางจะยังคงอยู่ในแถบที่อยู่แทนที่จะถูกแทนที่ด้วย URL ของ
chrome-extension:// - ส่วนขยายจะดึงการตอบกลับที่ Chrome ได้รับแล้ว แทนที่จะส่งคำขอเครือข่ายครั้งที่ 2 เอกสารที่ส่งโดยคำขอ POST หรือจาก URL แบบใช้ครั้งเดียวจะทำงานได้อย่างถูกต้อง
- ส่วนขยายสามารถแสดงผลเอกสารที่โหลดภายในองค์ประกอบ
<embed>,<object>หรือ<iframe> - ไฟล์ในเครื่อง (URL
file://) จะทำงานโดยที่ผู้ใช้ไม่ต้องเปิดใช้ "อนุญาตให้เข้าถึง URL ของไฟล์" ในการตั้งค่าของส่วนขยายด้วยตนเอง
เครื่องจัดการ MIME จะใช้กับเอกสารที่ใช้ทั้งเฟรมเท่านั้น ซึ่งได้แก่ การนําทางระดับบนสุดและเอกสารที่ฝัง โดยจะไม่มีผลกับทรัพยากรย่อยในบรรทัด (เช่น องค์ประกอบ <audio>, <img> หรือ <video>)
ลงทะเบียนตัวแฮนเดิล
หากต้องการลงทะเบียนส่วนขยายเป็นตัวแฮนเดิล MIME ให้ประกาศคีย์ "mime_types_handler" ใน manifest แต่ละรายการจะแมปประเภท MIME กับหน้าส่วนขยายที่แสดงผลประเภท MIME ดังกล่าว
manifest.json:
{
"name": "My PDF Viewer",
...
"mime_types_handler": {
"application/pdf": {
"handler_url": "viewer.html",
"can_embed": true
}
},
...
}
ตั้งค่า "can_embed" เป็น true เพื่อจัดการเอกสารที่ฝังในองค์ประกอบ <embed>, <object> หรือ <iframe> ด้วย หากไม่ระบุ แฮนเดิลจะได้รับการนําทางระดับบนสุดเท่านั้น ตั้งแต่ Chrome 151 เป็นต้นไป application/pdf จะเป็นประเภท MIME เดียวที่ใช้ได้กับเครื่องจัดการสาธารณะ การประกาศประเภท MIME ที่ไม่รองรับจะทำให้เกิดคำเตือนการติดตั้ง
หากมีส่วนขยายที่ติดตั้งมากกว่า 1 รายการลงทะเบียนสำหรับประเภท MIME เดียวกัน ส่วนขยายที่ติดตั้งล่าสุดจะเป็นตัวจัดการ หากถอนการติดตั้งส่วนขยายดังกล่าว ตัวแฮนเดิลที่ติดตั้งไว้ก่อนหน้านี้จะกลับมาทำงานอีกครั้ง
ดึงข้อมูลสตรีม
เมื่อผู้ใช้เปิดเอกสารประเภท MIME ที่ลงทะเบียนไว้ Chrome จะโหลดหน้าเครื่องจัดการแทนโปรแกรมดูในตัว จากหน้าเครื่องจัดการ ให้เรียก getStreamInfo() เพื่อดึงข้อมูลออบเจ็กต์ StreamInfo ซึ่งรวมถึง originalUrl ที่ผู้ใช้ไปยังส่วนต่างๆ, responseHeaders HTTP, เอกสารที่โหลดในบริบท embedded หรือไม่ และ streamUrl ที่ใช้ดึงเนื้อหาของเอกสารได้
streamUrl จะดึงข้อมูลได้เพียงครั้งเดียวและจากต้นทางของส่วนขยายเท่านั้น อ่านการตอบกลับทั้งหมดก่อนประมวลผล การดึงข้อมูล streamUrl เดียวกันครั้งที่ 2 จะไม่สำเร็จ ใช้ originalUrl เมื่อแสดงตำแหน่งหรือชื่อของเอกสาร ไม่ใช่เพื่อดึงข้อมูลเนื้อหา เนื่องจากคำขอเดิมอาจทำซ้ำไม่ได้
กลับไปใช้เครื่องจัดการแบบเนทีฟ
เครื่องจัดการอาจพบเอกสารที่แสดงผลไม่ได้ เช่น ไฟล์ที่เสียหายหรือไฟล์ที่ป้องกันด้วยรหัสผ่าน เรียกใช้ abortAndFallbackToNativeHandler() เพื่อหยุดจัดการเอกสารและส่งกลับไปยังโปรแกรมดูในตัวของ Chrome แทนที่จะปล่อยให้ผู้ใช้อยู่ในหน้าที่ใช้งานไม่ได้ Chrome จะยกเลิกการโหลดหน้าเว็บของเครื่องจัดการเป็นส่วนหนึ่งของกลไกสำรอง โดยจะไม่มีโค้ดทำงานหลังจากเรียกใช้เมธอดนี้
Chrome จะบัฟเฟอร์การตอบกลับขณะที่ตัวแฮนเดิลทำงาน หากได้รับการตอบกลับอย่างสมบูรณ์เมื่อคุณเรียกใช้เมธอดนี้ Chrome จะแสดงโปรแกรมดูในตัวจากสำเนาที่บัฟเฟอร์ไว้โดยไม่มีคำขอเครือข่ายใหม่ มิฉะนั้น Chrome จะโหลดเอกสารซ้ำจากเครือข่าย ซึ่งอาจดำเนินการไม่สำเร็จสำหรับเอกสารที่ส่งโดย POST หรือจาก URL ที่ใช้งานครั้งเดียว ดึงข้อมูลสตรีมให้ครบถ้วนก่อนตัดสินใจว่าจะแสดงผลได้หรือไม่ เมื่อดึงข้อมูล streamUrl เสร็จแล้ว Chrome จะได้รับการตอบกลับทั้งหมด
จัดการความพร้อมใช้งานของ API
ใน Chrome เวอร์ชันก่อน Chrome 151 ส่วนขยายที่ประกาศ "mime_types_handler" จะยังคงติดตั้งและทำงานได้ แต่จะไม่ได้ลงทะเบียนเป็นเครื่องจัดการ และ browser.mimeHandler จะไม่ได้กำหนดไว้ ส่วนขยายที่ย้ายข้อมูลจากการสกัดกั้นคำขอเครือข่ายสามารถตรวจสอบ API ได้เมื่อเริ่มต้นระบบ และเก็บแนวทางที่มีอยู่ไว้เป็นทางเลือกสำรอง ดังนี้
service-worker.js:
if (browser.mimeHandler) {
// Chrome routes registered MIME types to the handler page
// declared in the manifest.
} else {
// Fall back to network request interception.
}
ตัวอย่าง
จัดการสตรีม
ตัวอย่างต่อไปนี้จะทำงานในหน้าตัวแฮนเดิลที่ประกาศไว้ในไฟล์ Manifest โดยจะดึงเนื้อหาของเอกสารและเปลี่ยนไปใช้โปรแกรมดูในตัวของ Chrome หากแสดงผลไม่สำเร็จ ดังนี้
viewer.js:
async function loadDocument() {
const streamInfo = await browser.mimeHandler.getStreamInfo();
// The `embedded` property is true if the document is loaded
// within an <embed>, <object>, or <iframe> element.
if (streamInfo.embedded) {
// Adjust the UI (e.g., hide the top navigation bar).
document.body.classList.add('embedded-view');
}
// Fetch the content using the provided streamUrl. The stream can
// only be consumed once, so read it fully before continuing.
const response = await fetch(streamInfo.streamUrl);
const data = await response.arrayBuffer();
try {
// Render the document (e.g., using PDF.js).
await renderDocument(data);
} catch (e) {
// Can't render this document. Fall back to Chrome's built-in
// viewer; the page unloads and no code runs after this call.
browser.mimeHandler.abortAndFallbackToNativeHandler();
}
}
loadDocument();
อนุญาตให้ผู้ใช้เปิด/ปิดการจัดการ
ระบบจะจัดเก็บตัวเลือกเครื่องจัดการตามประเภท MIME ตัวอย่างต่อไปนี้ใช้ getMimeHandlerOptions() และ setMimeHandlerOptions() เพื่อให้ผู้ใช้ปิดการจัดการจากหน้าตัวเลือกได้โดยไม่ต้องถอนการติดตั้งส่วนขยาย เมื่อปิดใช้การจัดการ ระบบจะไม่กำหนดเส้นทางเอกสารประเภทนั้นไปยังส่วนขยายอีกต่อไป
options.js:
const checkbox = document.querySelector('#handle-pdfs');
async function initOptions() {
const options =
await browser.mimeHandler.getMimeHandlerOptions('application/pdf');
// Handling is enabled unless it has been explicitly disabled.
checkbox.checked = options.enabled !== false;
}
checkbox.addEventListener('change', async () => {
await browser.mimeHandler.setMimeHandlerOptions('application/pdf', {
enabled: checkbox.checked
});
});
initOptions();
ประเภท
MimeHandlerOptions
พร็อพเพอร์ตี้
-
canEmbed
บูลีน ไม่บังคับ
Chrome 157 ขึ้นไปใช้เครื่องจัดการนี้สำหรับการโหลดแบบฝัง (iframe, embed, object) ได้หรือไม่ ค่าเริ่มต้นจะเป็นค่า
can_embedของรายการไฟล์ Manifest ไม่มีผลขณะที่enabledเป็นเท็จ -
เปิดอยู่
บูลีน ไม่บังคับ
ตัวแฮนเดิลนี้เปิดใช้อยู่หรือไม่ ค่าเริ่มต้นจะเป็นค่า
enabledของรายการไฟล์ Manifest
StreamInfo
พร็อพเพอร์ตี้
-
แบบฝัง
บูลีน
เป็นจริงหากโหลดในบริบทที่ฝัง (iframe/embed/object)
-
mimeType
สตริง
ประเภท MIME ของเนื้อหาที่ถูกสกัดกั้น
-
originalUrl
สตริง
URL ต้นทางที่ผู้ใช้ไป
-
responseHeaders
ออบเจ็กต์
ส่วนหัวการตอบกลับ HTTP เป็นคู่คีย์-ค่า
-
streamUrl
สตริง
URL สำหรับดึงข้อมูลสตรีม
-
tabId
ตัวเลข
รหัสแท็บที่มีเอกสาร
เมธอด
abortAndFallbackToNativeHandler()
browser.mimeHandler.abortAndFallbackToNativeHandler(): Promise<void>
ยกเลิกการจัดการสตรีมปัจจุบันและส่งต่อเนื้อหาไปยังเครื่องมือจัดการแบบเนทีฟของ User Agent หลังจากเรียกใช้แล้ว เฟรมส่วนขยายจะถูกทำลาย ผู้เรียกไม่ควรคาดหวังให้มีการดำเนินการเพิ่มเติม
การคืนสินค้า
-
Promise<void>
getMimeHandlerOptions()
browser.mimeHandler.getMimeHandlerOptions(
mimeType: string,
): Promise<MimeHandlerOptions>
อ่านตัวเลือกสำหรับประเภท MIME สมาชิกแต่ละคนคือค่าที่ส่วนขยายตั้งค่าไว้ หรือค่าของรายการไฟล์ Manifest หากส่วนขยายไม่ได้ตั้งค่าไว้
พารามิเตอร์
-
mimeType
สตริง
ประเภท MIME ที่จะอ่านตัวเลือก โดยต้องเป็นประเภท MIME ที่ส่วนขยายจัดการผ่าน mime_types_handler
การคืนสินค้า
-
Promise<MimeHandlerOptions>
Promise ได้รับการแก้ไขด้วยตัวเลือกสำหรับประเภท MIME
getStreamInfo()
browser.mimeHandler.getStreamInfo(): Promise<StreamInfo>
เรียกดูข้อมูลสตรีมสำหรับบริบทของเครื่องจัดการ MIME ปัจจุบัน ต้องเรียกจากภายในหน้าส่วนขยายเครื่องจัดการ MIME
การคืนสินค้า
-
Promise<StreamInfo>
setMimeHandlerOptions()
browser.mimeHandler.setMimeHandlerOptions(
mimeType: string,
options: MimeHandlerOptions,
): Promise<void>
ตั้งค่าตัวเลือกการกำหนดค่าสำหรับประเภท MIME ที่ระบุ หากส่วนขยายทำงานในโหมดไม่ระบุตัวตนแบบแยก ตัวเลือกที่ตั้งค่าจากโหมดไม่ระบุตัวตนจะมีผลกับโหมดไม่ระบุตัวตนเท่านั้น และจะคงอยู่จนกว่าเซสชันไม่ระบุตัวตนจะสิ้นสุดลง ตัวเลือกที่ไม่ได้ตั้งค่าจากโหมดไม่ระบุตัวตนจะเป็นไปตามค่าที่ตั้งไว้นอกโหมดไม่ระบุตัวตน
พารามิเตอร์
-
mimeType
สตริง
ประเภท MIME ที่จะกำหนดค่า โดยต้องเป็นประเภท MIME ที่ส่วนขยายจัดการผ่าน mime_types_handler
-
ตัวเลือก
ตัวเลือกที่จะเปลี่ยนแปลง
การคืนสินค้า
-
Promise<void>
ระบบจะดำเนินการตามสัญญาเมื่อตั้งค่าการกำหนดค่าแล้ว