คำอธิบาย
ใช้ chrome.scripting
API เพื่อเรียกใช้สคริปต์ในบริบทต่างๆ
สิทธิ์
scripting
ความพร้อมใช้งาน
ไฟล์ Manifest
หากต้องการใช้ chrome.scripting
API ให้ประกาศสิทธิ์ "scripting"
ในไฟล์ Manifest พร้อมกับสิทธิ์ของโฮสต์สำหรับหน้าเว็บที่จะแทรกสคริปต์ ใช้คีย์ "host_permissions"
หรือสิทธิ์ "activeTab"
ซึ่งจะให้สิทธิ์ของโฮสต์ชั่วคราว ตัวอย่างต่อไปนี้ใช้สิทธิ์activeTab
{
"name": "Scripting Extension",
"manifest_version": 3,
"permissions": ["scripting", "activeTab"],
...
}
แนวคิดและการใช้งาน
คุณสามารถใช้ chrome.scripting
API เพื่อแทรก JavaScript และ CSS ลงใน
เว็บไซต์ ซึ่งคล้ายกับสิ่งที่คุณสามารถทำได้กับเนื้อหา
สคริปต์ แต่เมื่อใช้เนมสเปซ chrome.scripting
ส่วนขยาย
ตัดสินใจขณะรันไทม์ได้
เป้าหมายการแทรก
คุณใช้พารามิเตอร์ target
เพื่อระบุเป้าหมายที่จะแทรก JavaScript หรือ
CSS ลงใน
ช่องที่ต้องกรอกเพียงช่องเดียวคือ tabId
โดยค่าเริ่มต้น การแทรกจะทำงานใน
เฟรมหลักของแท็บที่ระบุ
function getTabId() { ... }
chrome.scripting
.executeScript({
target : {tabId : getTabId()},
files : [ "script.js" ],
})
.then(() => console.log("script injected"));
หากต้องการเรียกใช้ในเฟรมทั้งหมดของแท็บที่ระบุ คุณสามารถตั้งค่าบูลีน allFrames
ไปยัง true
function getTabId() { ... }
chrome.scripting
.executeScript({
target : {tabId : getTabId(), allFrames : true},
files : [ "script.js" ],
})
.then(() => console.log("script injected in all frames"));
คุณยังสามารถแทรกลงในเฟรมที่ต้องการของแท็บโดยการระบุแต่ละเฟรมได้ด้วย
รหัส ดูข้อมูลเพิ่มเติมเกี่ยวกับรหัสเฟรมได้ที่ chrome.webNavigation
API
function getTabId() { ... }
chrome.scripting
.executeScript({
target : {tabId : getTabId(), frameIds : [ frameId1, frameId2 ]},
files : [ "script.js" ],
})
.then(() => console.log("script injected on target frames"));
โค้ดที่แทรก
ส่วนขยายสามารถระบุโค้ดที่จะแทรกผ่านไฟล์ภายนอกหรือ ของตัวแปรรันไทม์
ไฟล์
ไฟล์ถูกระบุเป็นสตริงที่เป็นเส้นทางที่สัมพันธ์กับรากของส่วนขยาย
ไดเรกทอรี โค้ดต่อไปนี้จะแทรกไฟล์ script.js
ลงในไฟล์หลัก
เฟรมของแท็บ
function getTabId() { ... }
chrome.scripting
.executeScript({
target : {tabId : getTabId()},
files : [ "script.js" ],
})
.then(() => console.log("injected script file"));
ฟังก์ชันรันไทม์
เมื่อแทรก JavaScript ด้วย scripting.executeScript()
คุณสามารถระบุ
ที่จะเรียกใช้แทนไฟล์ ฟังก์ชันนี้ควรเป็นฟังก์ชัน
ที่พร้อมใช้งานในบริบทของส่วนขยายปัจจุบัน
function getTabId() { ... }
function getTitle() { return document.title; }
chrome.scripting
.executeScript({
target : {tabId : getTabId()},
func : getTitle,
})
.then(() => console.log("injected a function"));
function getTabId() { ... }
function getUserColor() { ... }
function changeBackgroundColor() {
document.body.style.backgroundColor = getUserColor();
}
chrome.scripting
.executeScript({
target : {tabId : getTabId()},
func : changeBackgroundColor,
})
.then(() => console.log("injected a function"));
คุณสามารถหลีกเลี่ยงปัญหานี้ได้โดยใช้พร็อพเพอร์ตี้ args
:
function getTabId() { ... }
function getUserColor() { ... }
function changeBackgroundColor(backgroundColor) {
document.body.style.backgroundColor = backgroundColor;
}
chrome.scripting
.executeScript({
target : {tabId : getTabId()},
func : changeBackgroundColor,
args : [ getUserColor() ],
})
.then(() => console.log("injected a function"));
สตริงรันไทม์
หากใส่ CSS ภายในหน้าเว็บ คุณสามารถระบุสตริงที่จะใช้ใน
พร็อพเพอร์ตี้ css
ตัวเลือกนี้ใช้ได้กับ scripting.insertCSS()
เท่านั้น คุณ
ไม่สามารถเรียกใช้สตริงโดยใช้ scripting.executeScript()
function getTabId() { ... }
const css = "body { background-color: red; }";
chrome.scripting
.insertCSS({
target : {tabId : getTabId()},
css : css,
})
.then(() => console.log("CSS injected"));
จัดการผลลัพธ์
ระบบจะส่งผลลัพธ์ของการเรียกใช้ JavaScript ไปยังส่วนขยาย ผลลัพธ์รายการเดียว รวมต่อเฟรม เฟรมหลักเป็นดัชนีแรกใน อาร์เรย์ผลลัพธ์ เฟรมอื่นๆ ทั้งหมดอยู่ในลำดับที่ไม่กำหนด
function getTabId() { ... }
function getTitle() { return document.title; }
chrome.scripting
.executeScript({
target : {tabId : getTabId(), allFrames : true},
func : getTitle,
})
.then(injectionResults => {
for (const {frameId, result} of injectionResults) {
console.log(`Frame ${frameId} result:`, result);
}
});
scripting.insertCSS()
ไม่แสดงผลลัพธ์ใดๆ
คำสัญญา
หากผลลัพธ์ของสคริปต์มีค่าที่บอกไว้ Chrome จะรอ สำหรับสัญญาว่าจะชำระและแสดงผลมูลค่าที่ได้
function getTabId() { ... }
async function addIframe() {
const iframe = document.createElement("iframe");
const loadComplete =
new Promise(resolve => iframe.addEventListener("load", resolve));
iframe.src = "https://example.com";
document.body.appendChild(iframe);
await loadComplete;
return iframe.contentWindow.document.title;
}
chrome.scripting
.executeScript({
target : {tabId : getTabId(), allFrames : true},
func : addIframe,
})
.then(injectionResults => {
for (const frameResult of injectionResults) {
const {frameId, result} = frameResult;
console.log(`Frame ${frameId} result:`, result);
}
});
ตัวอย่าง
ยกเลิกการลงทะเบียนสคริปต์เนื้อหาแบบไดนามิกทั้งหมด
ข้อมูลโค้ดต่อไปนี้มีฟังก์ชันที่ยกเลิกการลงทะเบียนเนื้อหาแบบไดนามิกทั้งหมด สคริปต์ที่ส่วนขยายได้ลงทะเบียนไว้ก่อนหน้านี้
async function unregisterAllDynamicContentScripts() {
try {
const scripts = await chrome.scripting.getRegisteredContentScripts();
const scriptIds = scripts.map(script => script.id);
return chrome.scripting.unregisterContentScripts(scriptIds);
} catch (error) {
const message = [
"An unexpected error occurred while",
"unregistering dynamic content scripts.",
].join(" ");
throw new Error(message, {cause : error});
}
}
หากต้องการลองใช้ chrome.scripting
API
ติดตั้งตัวอย่างสคริปต์จากตัวอย่างส่วนขยาย Chrome
ที่เก็บได้
ประเภท
ContentScriptFilter
พร็อพเพอร์ตี้
-
รหัส
string[] ไม่บังคับ
หากระบุไว้
getRegisteredContentScripts
จะแสดงผลสคริปต์ที่มีรหัสที่ระบุไว้ในรายการนี้เท่านั้น
CSSInjection
พร็อพเพอร์ตี้
-
CSS
string ไม่บังคับ
สตริงที่มี CSS ที่จะแทรก ต้องระบุ
files
และcss
เพียง 1 รายการ -
files
string[] ไม่บังคับ
เส้นทางของไฟล์ CSS ที่จะแทรก ซึ่งสัมพันธ์กับไดเรกทอรีรากของส่วนขยาย ต้องระบุ
files
และcss
เพียง 1 รายการ -
origin
StyleOrigin ไม่บังคับ
ต้นทางของรูปแบบสำหรับการแทรก ค่าเริ่มต้นคือ
'AUTHOR'
-
เป้าหมาย
รายละเอียดที่ระบุเป้าหมายที่จะแทรก CSS
ExecutionWorld
โลก JavaScript ที่สคริปต์จะทำงานภายใน
ค่าแจกแจง
"ISOLATED"
ระบุโลกที่โดดเดี่ยว ซึ่งเป็นสภาพแวดล้อมการดำเนินการเฉพาะสำหรับส่วนขยายนี้
"MAIN"
ระบุโลกหลักของ DOM ซึ่งเป็นสภาพแวดล้อมการดำเนินการที่แชร์กับ JavaScript ของหน้าโฮสต์
InjectionResult
พร็อพเพอร์ตี้
-
documentId
สตริง
Chrome 106 ขึ้นไปเอกสารที่เชื่อมโยงกับการแทรก
-
frameId
ตัวเลข
Chrome 90 ขึ้นไปเฟรมที่เชื่อมโยงกับการแทรก
-
ผลลัพธ์
ใดก็ได้ไม่บังคับ
ผลของการเรียกใช้สคริปต์
InjectionTarget
พร็อพเพอร์ตี้
-
allFrames
บูลีน ไม่บังคับ
สคริปต์ควรแทรกลงในเฟรมทั้งหมดภายในแท็บไหม ค่าเริ่มต้นคือ "เท็จ" ค่านี้ต้องไม่เป็นความจริงหากระบุ
frameIds
ไว้ -
documentIds
string[] ไม่บังคับ
Chrome 106 ขึ้นไปรหัสของ documentId เฉพาะที่จะแทรก ต้องไม่ตั้งค่านี้หากตั้งค่า
frameIds
ไว้ -
frameIds
number[] ไม่บังคับ
รหัสของเฟรมเฉพาะที่จะแทรก
-
tabId
ตัวเลข
รหัสของแท็บที่จะแทรก
RegisteredContentScript
พร็อพเพอร์ตี้
-
allFrames
บูลีน ไม่บังคับ
หากระบุเป็น "จริง" ระบบจะแทรกลงในเฟรมทั้งหมด แม้ว่าเฟรมจะไม่ใช่เฟรมบนสุดในแท็บก็ตาม แต่ละเฟรมจะได้รับการตรวจสอบแยกกันสำหรับข้อกําหนดของ URL ระบบจะไม่แทรกเฟรมย่อยหากไม่เป็นไปตามข้อกำหนดของ URL ค่าเริ่มต้นคือ "เท็จ" ซึ่งหมายความว่าระบบจะจับคู่เฉพาะเฟรมบนสุดเท่านั้น
-
CSS
string[] ไม่บังคับ
รายการไฟล์ CSS ที่จะแทรกลงในหน้าที่ตรงกัน ข้อมูลเหล่านี้จะแทรกตามลำดับที่ปรากฏในอาร์เรย์นี้ ก่อนที่จะมีการสร้างหรือแสดง DOM สำหรับหน้าเว็บ
-
excludeMatches
string[] ไม่บังคับ
ยกเว้นหน้าที่มีการแทรกสคริปต์เนื้อหานี้ ดูรูปแบบการจับคู่สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับไวยากรณ์ของสตริงเหล่านี้
-
id
สตริง
รหัสของสคริปต์เนื้อหาที่ระบุในการเรียก API ต้องไม่ขึ้นต้นด้วย '_' เนื่องจากสงวนไว้เป็นคำนำหน้าสำหรับรหัสสคริปต์ที่สร้างขึ้น
-
JS
string[] ไม่บังคับ
รายการไฟล์ JavaScript ที่จะแทรกลงในหน้าที่ตรงกัน ซึ่งจะแทรกตามลำดับที่ปรากฏในอาร์เรย์
-
matchOriginAsFallback
บูลีน ไม่บังคับ
Chrome 119 ขึ้นไประบุว่าสามารถแทรกสคริปต์ลงในเฟรมที่ URL มีรูปแบบที่ไม่รองรับหรือไม่ โดยเฉพาะ: about:, data:, blob: หรือ filesystem: ในกรณีเหล่านี้ ระบบจะตรวจสอบต้นทางของ URL เพื่อดูว่าควรแทรกสคริปต์หรือไม่ หากต้นทางคือ
null
(ในกรณีสำหรับข้อมูล URL) ต้นทางที่ใช้จะเป็นเฟรมที่สร้างเฟรมปัจจุบันหรือเฟรมที่เริ่มต้นการนำทางไปยังเฟรมนี้ โปรดทราบว่านี่อาจไม่ใช่เฟรมหลัก -
ตรงกับ
string[] ไม่บังคับ
ระบุหน้าที่จะแทรกสคริปต์เนื้อหานี้ ดูรูปแบบการจับคู่สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับไวยากรณ์ของสตริงเหล่านี้ ต้องระบุสำหรับ
registerContentScripts
-
persistAcrossSessions
บูลีน ไม่บังคับ
ระบุว่าสคริปต์เนื้อหาจะยังคงอยู่ในเซสชันในอนาคตหรือไม่ ค่าเริ่มต้นคือ True
-
runAt
RunAt ไม่บังคับ
ระบุเมื่อมีการแทรกไฟล์ JavaScript ลงในหน้าเว็บ ค่าที่ต้องการและค่าเริ่มต้นคือ
document_idle
-
โลก
ExecutionWorld ไม่บังคับ
Chrome 102 ขึ้นไป"โลก" ของ JavaScript สำหรับเรียกใช้สคริปต์ ค่าเริ่มต้นคือ
ISOLATED
ScriptInjection
พร็อพเพอร์ตี้
-
อาร์กิวเมนต์
any[] ไม่บังคับ
Chrome 92 ขึ้นไปอาร์กิวเมนต์ที่จะส่งไปยังฟังก์ชันที่ระบุ ซึ่งจะใช้ได้หากมีการระบุพารามิเตอร์
func
ไว้เท่านั้น อาร์กิวเมนต์เหล่านี้ต้องสามารถทำให้อนุกรม JSON ได้ -
files
string[] ไม่บังคับ
เส้นทางของไฟล์ JS หรือ CSS ที่จะแทรก ซึ่งสัมพันธ์กับไดเรกทอรีรากของส่วนขยาย ต้องระบุ
files
หรือfunc
เพียง 1 รายการ -
injectImmediately
บูลีน ไม่บังคับ
Chrome 102 ขึ้นไปควรทริกเกอร์การแทรกในเป้าหมายโดยเร็วที่สุดหรือไม่ โปรดทราบว่านี่ไม่ใช่การรับประกันว่าจะมีการแทรกเกิดขึ้นก่อนการโหลดหน้าเว็บ เนื่องจากหน้าเว็บอาจโหลดแล้วก่อนที่สคริปต์จะถึงเป้าหมาย
-
เป้าหมาย
รายละเอียดที่ระบุเป้าหมายที่จะแทรกสคริปต์
-
โลก
ExecutionWorld ไม่บังคับ
Chrome 95 ขึ้นไป"โลก" ของ JavaScript สำหรับเรียกใช้สคริปต์ ค่าเริ่มต้นคือ
ISOLATED
-
func
เป็นโมฆะ ไม่บังคับ
Chrome 92 ขึ้นไปฟังก์ชัน JavaScript ที่จะแทรก ฟังก์ชันนี้จะได้รับการทำให้เป็นอนุกรม จากนั้นดีซีเรียลไลซ์สำหรับการแทรก ซึ่งหมายความว่าพารามิเตอร์ที่เชื่อมโยงและบริบทการดำเนินการจะหายไป ต้องระบุ
files
หรือfunc
เพียง 1 รายการฟังก์ชัน
func
มีลักษณะดังนี้() => {...}
StyleOrigin
ต้นทางของการเปลี่ยนรูปแบบ ดูข้อมูลเพิ่มเติมในที่มาของรูปแบบ
ค่าแจกแจง
"AUTHOR"
"ผู้ใช้"
เมธอด
executeScript()
chrome.scripting.executeScript(
injection: ScriptInjection,
callback?: function,
)
แทรกสคริปต์ลงในบริบทเป้าหมาย โดยค่าเริ่มต้น สคริปต์จะทำงานที่ document_idle
หรือทันทีหากหน้าเว็บโหลดเสร็จแล้ว หากตั้งค่าพร็อพเพอร์ตี้ injectImmediately
สคริปต์จะแทรกโดยไม่ต้องรอ แม้ว่าหน้าเว็บจะโหลดไม่เสร็จก็ตาม หากสคริปต์ประเมินผลสำเร็จ เบราว์เซอร์จะรอให้การสัญญากำหนดและแสดงผลค่าที่เป็นผลลัพธ์
พารามิเตอร์
-
การฉีดยา
รายละเอียดของสคริปต์ที่จะแทรก
-
Callback
ไม่บังคับ
พารามิเตอร์
callback
มีลักษณะดังนี้(results: InjectionResult[]) => void
-
ผลลัพธ์
-
การคืนสินค้า
-
Promise<InjectionResult[]>
Chrome 90 ขึ้นไปรองรับคำสัญญาในไฟล์ Manifest V3 ขึ้นไป แต่จะมี Callback สำหรับ ความเข้ากันได้แบบย้อนหลัง คุณไม่สามารถใช้ทั้ง 2 อย่างในการเรียกใช้ฟังก์ชันเดียวกันได้ จะมีการแก้ไขด้วยประเภทเดียวกันที่ส่งไปยัง Callback
getRegisteredContentScripts()
chrome.scripting.getRegisteredContentScripts(
filter?: ContentScriptFilter,
callback?: function,
)
แสดงสคริปต์เนื้อหาที่ลงทะเบียนแบบไดนามิกทั้งหมดสำหรับส่วนขยายนี้ซึ่งตรงกับตัวกรองที่ระบุ
พารามิเตอร์
-
ตัวกรอง
ContentScriptFilter ไม่บังคับ
ออบเจ็กต์สำหรับกรองสคริปต์ที่ลงทะเบียนแบบไดนามิกของส่วนขยาย
-
Callback
ไม่บังคับ
พารามิเตอร์
callback
มีลักษณะดังนี้(scripts: RegisteredContentScript[]) => void
-
สคริปต์
-
การคืนสินค้า
-
Promise<RegisteredContentScript[]>
รองรับคำสัญญาในไฟล์ Manifest V3 ขึ้นไป แต่จะมี Callback สำหรับ ความเข้ากันได้แบบย้อนหลัง คุณไม่สามารถใช้ทั้ง 2 อย่างในการเรียกใช้ฟังก์ชันเดียวกันได้ จะมีการแก้ไขด้วยประเภทเดียวกันที่ส่งไปยัง Callback
insertCSS()
chrome.scripting.insertCSS(
injection: CSSInjection,
callback?: function,
)
แทรกสไตล์ชีต CSS ในบริบทเป้าหมาย หากระบุเฟรมหลายเฟรม ระบบจะละเว้นการแทรกที่ไม่สำเร็จ
พารามิเตอร์
-
การฉีดยา
รายละเอียดของรูปแบบที่จะแทรก
-
Callback
ไม่บังคับ
พารามิเตอร์
callback
มีลักษณะดังนี้() => void
การคืนสินค้า
-
คำมั่นสัญญา<โมฆะ>
Chrome 90 ขึ้นไปรองรับคำสัญญาในไฟล์ Manifest V3 ขึ้นไป แต่จะมี Callback สำหรับ ความเข้ากันได้แบบย้อนหลัง คุณไม่สามารถใช้ทั้ง 2 อย่างในการเรียกใช้ฟังก์ชันเดียวกันได้ จะมีการแก้ไขด้วยประเภทเดียวกันที่ส่งไปยัง Callback
registerContentScripts()
chrome.scripting.registerContentScripts(
scripts: RegisteredContentScript[],
callback?: function,
)
ลงทะเบียนสคริปต์เนื้อหาอย่างน้อย 1 รายการสำหรับส่วนขยายนี้
พารามิเตอร์
-
สคริปต์
มีรายการสคริปต์ที่จะลงทะเบียน หากมีข้อผิดพลาดระหว่างการแยกวิเคราะห์สคริปต์/การตรวจสอบไฟล์ หรือหากมีรหัสที่ระบุอยู่แล้ว แสดงว่าไม่มีการบันทึกสคริปต์
-
Callback
ไม่บังคับ
พารามิเตอร์
callback
มีลักษณะดังนี้() => void
การคืนสินค้า
-
คำมั่นสัญญา<โมฆะ>
รองรับคำสัญญาในไฟล์ Manifest V3 ขึ้นไป แต่จะมี Callback สำหรับ ความเข้ากันได้แบบย้อนหลัง คุณไม่สามารถใช้ทั้ง 2 อย่างในการเรียกใช้ฟังก์ชันเดียวกันได้ จะมีการแก้ไขด้วยประเภทเดียวกันที่ส่งไปยัง Callback
removeCSS()
chrome.scripting.removeCSS(
injection: CSSInjection,
callback?: function,
)
นำสไตล์ชีต CSS ที่ส่วนขยายนี้แทรกไว้ก่อนหน้านี้ออกจากบริบทเป้าหมาย
พารามิเตอร์
-
การฉีดยา
รายละเอียดของรูปแบบที่จะนำออก โปรดทราบว่าคุณสมบัติ
css
,files
และorigin
ต้องตรงกับสไตล์ชีตที่แทรกผ่านinsertCSS
ทุกประการ การพยายามนำสไตล์ชีตที่ไม่มีอยู่ออกเป็นสิ่งที่ทำไม่ได้ -
Callback
ไม่บังคับ
พารามิเตอร์
callback
มีลักษณะดังนี้() => void
การคืนสินค้า
-
คำมั่นสัญญา<โมฆะ>
รองรับคำสัญญาในไฟล์ Manifest V3 ขึ้นไป แต่จะมี Callback สำหรับ ความเข้ากันได้แบบย้อนหลัง คุณไม่สามารถใช้ทั้ง 2 อย่างในการเรียกใช้ฟังก์ชันเดียวกันได้ จะมีการแก้ไขด้วยประเภทเดียวกันที่ส่งไปยัง Callback
unregisterContentScripts()
chrome.scripting.unregisterContentScripts(
filter?: ContentScriptFilter,
callback?: function,
)
ยกเลิกการลงทะเบียนสคริปต์เนื้อหาสำหรับส่วนขยายนี้
พารามิเตอร์
-
ตัวกรอง
ContentScriptFilter ไม่บังคับ
หากระบุ จะยกเลิกการลงทะเบียนสคริปต์เนื้อหาแบบไดนามิกที่ตรงกับตัวกรองเท่านั้น มิฉะนั้น สคริปต์เนื้อหาแบบไดนามิกทั้งหมดของส่วนขยายจะถูกยกเลิกการลงทะเบียน
-
Callback
ไม่บังคับ
พารามิเตอร์
callback
มีลักษณะดังนี้() => void
การคืนสินค้า
-
คำมั่นสัญญา<โมฆะ>
รองรับคำสัญญาในไฟล์ Manifest V3 ขึ้นไป แต่จะมี Callback สำหรับ ความเข้ากันได้แบบย้อนหลัง คุณไม่สามารถใช้ทั้ง 2 อย่างในการเรียกใช้ฟังก์ชันเดียวกันได้ จะมีการแก้ไขด้วยประเภทเดียวกันที่ส่งไปยัง Callback
updateContentScripts()
chrome.scripting.updateContentScripts(
scripts: RegisteredContentScript[],
callback?: function,
)
อัปเดตสคริปต์เนื้อหาอย่างน้อย 1 รายการสำหรับส่วนขยายนี้
พารามิเตอร์
-
สคริปต์
มีรายการสคริปต์ที่จะอัปเดต ระบบจะอัปเดตคุณสมบัติสำหรับสคริปต์ที่มีอยู่ก็ต่อเมื่อมีการระบุไว้ในออบเจ็กต์นี้ หากมีข้อผิดพลาดระหว่างการแยกวิเคราะห์สคริปต์/การตรวจสอบไฟล์ หรือหากรหัสที่ระบุไม่ตรงกับสคริปต์ที่ลงทะเบียนอย่างสมบูรณ์ ก็จะไม่มีการอัปเดตสคริปต์
-
Callback
ไม่บังคับ
พารามิเตอร์
callback
มีลักษณะดังนี้() => void
การคืนสินค้า
-
คำมั่นสัญญา<โมฆะ>
รองรับคำสัญญาในไฟล์ Manifest V3 ขึ้นไป แต่จะมี Callback สำหรับ ความเข้ากันได้แบบย้อนหลัง คุณไม่สามารถใช้ทั้ง 2 อย่างในการเรียกใช้ฟังก์ชันเดียวกันได้ จะมีการแก้ไขด้วยประเภทเดียวกันที่ส่งไปยัง Callback