คำอธิบาย
ใช้ offscreen API เพื่อสร้างและจัดการเอกสารนอกหน้าจอ
สิทธิ์
offscreenหากต้องการใช้ Offscreen API ให้ประกาศสิทธิ์ "offscreen" ในไฟล์ Manifest ของส่วนขยาย เช่น
{
"name": "My extension",
...
"permissions": [
"offscreen"
],
...
}
ความพร้อมใช้งาน
แนวคิดและการใช้งาน
Service Worker ไม่มีสิทธิ์เข้าถึง DOM และเว็บไซต์จำนวนมากมีนโยบายรักษาความปลอดภัยเนื้อหาที่จำกัดฟังก์ชันการทำงานของสคริปต์เนื้อหา Offscreen API ช่วยให้ส่วนขยายใช้ DOM API ในเอกสารที่ซ่อนอยู่ได้โดยไม่รบกวนประสบการณ์ของผู้ใช้ด้วยการเปิดหน้าต่างหรือแท็บใหม่ API runtime เป็น API ส่วนขยายเพียงรายการเดียวที่เอกสารนอกหน้าจอรองรับ
หน้าเว็บที่โหลดเป็นเอกสารนอกหน้าจอจะได้รับการจัดการแตกต่างจากหน้าส่วนขยายประเภทอื่นๆ
สิทธิ์ของส่วนขยายจะส่งต่อไปยังเอกสารนอกหน้าจอ แต่จะมีการจำกัดการเข้าถึง API ของส่วนขยาย ตัวอย่างเช่น เนื่องจาก browser.runtime API เป็น API ส่วนขยายเพียงรายการเดียวที่เอกสารนอกหน้าจอรองรับ จึงต้องจัดการการรับส่งข้อความโดยใช้สมาชิกของ API ดังกล่าว
ต่อไปนี้เป็นวิธีอื่นๆ ที่เอกสารนอกหน้าจอทำงานแตกต่างจากหน้าเว็บปกติ
- URL ของเอกสารนอกหน้าจอต้องเป็นไฟล์ HTML แบบคงที่ซึ่งรวมอยู่ในส่วนขยาย
- เอกสารนอกหน้าจอไม่สามารถโฟกัสได้
- เอกสารนอกหน้าจอเป็นอินสแตนซ์ของ
windowแต่ค่าของพร็อพเพอร์ตี้openerจะเป็นnullเสมอ - แม้ว่าแพ็กเกจส่วนขยายจะมีเอกสารนอกหน้าจอได้หลายรายการ แต่ส่วนขยายที่ติดตั้งจะเปิดได้ครั้งละ 1 รายการเท่านั้น หากส่วนขยายทำงานในโหมดแยกโดยมีโปรไฟล์ที่ไม่ระบุตัวตนที่ใช้งานอยู่ โปรไฟล์ปกติและโปรไฟล์ที่ไม่ระบุตัวตนจะมีเอกสารนอกหน้าจอได้โปรไฟล์ละ 1 รายการ
ใช้ browser.offscreen.createDocument() และ browser.offscreen.closeDocument() เพื่อสร้างและปิดเอกสารนอกหน้าจอ createDocument() ต้องใช้ url ของเอกสาร เหตุผล และเหตุผลรองรับ ดังนี้
browser.offscreen.createDocument({
url: 'off_screen.html',
reasons: ['CLIPBOARD'],
justification: 'reason for needing the document',
});
เหตุผล
ดูรายการเหตุผลที่ถูกต้องได้ในส่วนเหตุผล ระบบจะตั้งค่าเหตุผลในระหว่างการสร้างเอกสารเพื่อกำหนดอายุการใช้งานของเอกสาร เหตุผล AUDIO_PLAYBACK จะตั้งค่าให้เอกสารปิดหลังจากผ่านไป 30 วินาทีโดยไม่มีการเล่นเสียง ส่วนเหตุผลอื่นๆ ทั้งหมดจะไม่กำหนดขีดจำกัดตลอดอายุการใช้งาน
ตัวอย่าง
คงวงจรของเอกสารนอกหน้าจอไว้
ตัวอย่างต่อไปนี้แสดงวิธีตรวจสอบว่ามีเอกสารนอกหน้าจออยู่ ฟังก์ชัน setupOffscreenDocument() จะเรียกใช้ runtime.getContexts() เพื่อค้นหาเอกสารนอกหน้าจอที่มีอยู่ หรือสร้างเอกสารหากยังไม่มี
let creating; // A global promise to avoid concurrency issues
async function setupOffscreenDocument(path) {
// Check all windows controlled by the service worker to see if one
// of them is the offscreen document with the given path
const offscreenUrl = browser.runtime.getURL(path);
const existingContexts = await browser.runtime.getContexts({
contextTypes: ['OFFSCREEN_DOCUMENT'],
documentUrls: [offscreenUrl]
});
if (existingContexts.length > 0) {
return;
}
// create offscreen document
if (creating) {
await creating;
} else {
creating = browser.offscreen.createDocument({
url: path,
reasons: ['CLIPBOARD'],
justification: 'reason for needing the document',
});
await creating;
creating = null;
}
}
ก่อนส่งข้อความไปยังเอกสารนอกหน้าจอ ให้เรียกใช้ setupOffscreenDocument() เพื่อตรวจสอบว่ามีเอกสารอยู่จริง ดังที่แสดงในตัวอย่างต่อไปนี้
browser.action.onClicked.addListener(async () => {
await setupOffscreenDocument('off_screen.html');
// Send message to offscreen document
browser.runtime.sendMessage({
type: '...',
target: 'offscreen',
data: '...'
});
});
ดูตัวอย่างที่สมบูรณ์ได้ที่เดโม offscreen-clipboard และ offscreen-dom ใน GitHub
ก่อน Chrome 116: ตรวจสอบว่าเอกสารนอกหน้าจอเปิดอยู่หรือไม่
runtime.getContexts() เพิ่มเข้ามาใน Chrome 116 ใน Chrome เวอร์ชันก่อนหน้า ให้ใช้ clients.matchAll() เพื่อตรวจสอบเอกสารนอกหน้าจอที่มีอยู่ ดังนี้
async function hasOffscreenDocument() {
if ('getContexts' in browser.runtime) {
const contexts = await browser.runtime.getContexts({
contextTypes: ['OFFSCREEN_DOCUMENT'],
documentUrls: [OFFSCREEN_DOCUMENT_PATH]
});
return Boolean(contexts.length);
} else {
const matchedClients = await clients.matchAll();
return matchedClients.some(client => {
return client.url.includes(browser.runtime.id);
});
}
}
ประเภท
CreateParameters
พร็อพเพอร์ตี้
-
เหตุผลรองรับ
สตริง
สตริงที่นักพัฒนาแอปให้ไว้ซึ่งอธิบายรายละเอียดเพิ่มเติมเกี่ยวกับความจำเป็นในการใช้บริบทเบื้องหลัง User Agent _อาจ_ใช้ข้อมูลนี้ในการแสดงต่อผู้ใช้
-
เหตุผล
เหตุผล[]
เหตุผลที่ส่วนขยายสร้างเอกสารนอกหน้าจอ
-
URL
สตริง
URL (แบบสัมพัทธ์) ที่จะโหลดในเอกสาร
Reason
ค่าแจกแจง
"TESTING"
เหตุผลที่ใช้เพื่อการทดสอบเท่านั้น
"AUDIO_PLAYBACK"
ระบุว่าเอกสารนอกหน้าจอมีหน้าที่เล่นเสียง
"IFRAME_SCRIPTING"
ระบุว่าเอกสารนอกหน้าจอจำเป็นต้องฝังและเขียนสคริปต์ iframe เพื่อแก้ไขเนื้อหาของ iframe
"DOM_SCRAPING"
ระบุว่าเอกสารนอกหน้าจอต้องฝัง iframe และสแครป DOM เพื่อดึงข้อมูล
"BLOBS"
ระบุว่าเอกสารนอกหน้าจอต้องโต้ตอบกับออบเจ็กต์ Blob (รวมถึง URL.createObjectURL())
"DOM_PARSER"
ระบุว่าเอกสารนอกหน้าจอต้องใช้ DOMParser API
"USER_MEDIA"
ระบุว่าเอกสารนอกหน้าจอต้องโต้ตอบกับสตรีมสื่อจากสื่อของผู้ใช้ (เช่น getUserMedia())
"DISPLAY_MEDIA"
ระบุว่าเอกสารนอกหน้าจอต้องโต้ตอบกับสตรีมสื่อจากสื่อที่แสดง (เช่น getDisplayMedia())
"WEB_RTC"
ระบุว่าเอกสารนอกหน้าจอต้องใช้ WebRTC API
"CLIPBOARD"
ระบุว่าเอกสารนอกหน้าจอต้องโต้ตอบกับ Clipboard API
"LOCAL_STORAGE"
ระบุว่าเอกสารนอกหน้าจอต้องเข้าถึง localStorage
"WORKERS"
ระบุว่าเอกสารนอกหน้าจอจำเป็นต้องสร้างผู้ปฏิบัติงาน
"BATTERY_STATUS"
ระบุว่าเอกสารนอกหน้าจอต้องใช้ navigator.getBattery
"MATCH_MEDIA"
ระบุว่าเอกสารนอกหน้าจอต้องใช้ window.matchMedia
"GEOLOCATION"
ระบุว่าเอกสารนอกหน้าจอต้องใช้ navigator.geolocation
เมธอด
closeDocument()
browser.offscreen.closeDocument(): Promise<void>
ปิดเอกสารนอกหน้าจอที่เปิดอยู่สำหรับส่วนขยาย
การคืนสินค้า
-
Promise<void>
Promise ที่จะได้รับการแก้ไขเมื่อปิดเอกสารนอกหน้าจอแล้ว
createDocument()
browser.offscreen.createDocument(
parameters: CreateParameters,
): Promise<void>
สร้างเอกสารนอกหน้าจอใหม่สำหรับส่วนขยาย
พารามิเตอร์
-
พารามิเตอร์
พารามิเตอร์ที่อธิบายเอกสารนอกหน้าจอที่จะสร้าง
การคืนสินค้า
-
Promise<void>
Promise ที่จะได้รับการแก้ไขเมื่อมีการสร้างเอกสารนอกหน้าจอและโหลดหน้าเว็บเริ่มต้นเสร็จสมบูรณ์
hasDocument()
browser.offscreen.hasDocument(): Promise<boolean>
ระบุว่าส่วนขยายมีเอกสารที่ใช้งานอยู่หรือไม่
การคืนสินค้า
-
Promise<boolean>
Promise ที่แก้ไขด้วยผลลัพธ์ว่าส่วนขยายมีเอกสารนอกหน้าจอที่ใช้งานอยู่หรือไม่