chrome.scripting

คำอธิบาย

ใช้ chrome.scripting API เพื่อเรียกใช้สคริปต์ในบริบทต่างๆ

สิทธิ์

scripting

ความพร้อมใช้งาน

Chrome 88 ขึ้นไป MV3 ขึ้นไป

ไฟล์ 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 boolean เป็น 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() ไม่แสดงผลลัพธ์ใดๆ

สัญญา

หากค่าที่ได้จากการเรียกใช้สคริปต์เป็น Promise Chrome จะรอให้ Promise เสร็จสมบูรณ์และแสดงผลค่าที่ได้

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({ ids: 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

Chrome 96 ขึ้นไป

พร็อพเพอร์ตี้

  • ids

    string[] ไม่บังคับ

    หากระบุ getRegisteredContentScripts ระบบจะแสดงเฉพาะสคริปต์ที่มีรหัสที่ระบุในรายการนี้เท่านั้น

CSSInjection

พร็อพเพอร์ตี้

  • CSS

    สตริง ไม่บังคับ

    สตริงที่มี CSS ที่จะแทรก ต้องระบุ files และ css อย่างใดอย่างหนึ่งเท่านั้น

  • ไฟล์

    string[] ไม่บังคับ

    เส้นทางของไฟล์ CSS ที่จะแทรก ซึ่งสัมพันธ์กับไดเรกทอรีรากของส่วนขยาย ต้องระบุ files และ css อย่างใดอย่างหนึ่งเท่านั้น

  • origin

    StyleOrigin ไม่บังคับ

    แหล่งที่มาของสไตล์สำหรับการแทรก ค่าเริ่มต้นคือ 'AUTHOR'

  • เป้าหมาย

    รายละเอียดที่ระบุเป้าหมายที่จะแทรก CSS

ExecutionWorld

Chrome 95 ขึ้นไป

โลกของ JavaScript สำหรับสคริปต์ที่จะดำเนินการภายใน

ค่าแจกแจง

"ISOLATED"
ระบุเวิลด์ที่แยกต่างหาก ซึ่งเป็นสภาพแวดล้อมการดำเนินการเฉพาะสำหรับส่วนขยายนี้

"MAIN"
ระบุโลกหลักของ DOM ซึ่งเป็นสภาพแวดล้อมการดำเนินการที่แชร์กับ JavaScript ของหน้าโฮสต์

InjectionResult

พร็อพเพอร์ตี้

  • documentId

    สตริง

    Chrome 106 ขึ้นไป

    เอกสารที่เชื่อมโยงกับการแทรก

  • frameId

    ตัวเลข

    Chrome 90 ขึ้นไป

    เฟรมที่เชื่อมโยงกับการแทรก

  • ผลลัพธ์

    ไม่บังคับ

    ผลลัพธ์ของการดำเนินการสคริปต์

InjectionTarget

พร็อพเพอร์ตี้

  • allFrames

    บูลีน ไม่บังคับ

    เลือกว่าสคริปต์ควรแทรกลงในเฟรมทั้งหมดภายในแท็บหรือไม่ ค่าเริ่มต้นคือ false ค่านี้ต้องเป็นเท็จหากมีการระบุ frameIds

  • documentIds

    string[] ไม่บังคับ

    Chrome 106 ขึ้นไป

    รหัสของ documentId ที่เฉพาะเจาะจงที่จะแทรก ห้ามตั้งค่านี้หากตั้งค่า frameIds ไว้

  • frameIds

    number[] ไม่บังคับ

    รหัสของเฟรมที่เฉพาะเจาะจงที่จะแทรก

  • tabId

    ตัวเลข

    รหัสของแท็บที่จะแทรก

RegisteredContentScript

Chrome 96 ขึ้นไป

พร็อพเพอร์ตี้

  • allFrames

    บูลีน ไม่บังคับ

    หากระบุเป็นจริง ระบบจะแทรกลงในทุกเฟรม แม้ว่าเฟรมจะไม่ใช่เฟรมบนสุดในแท็บก็ตาม ระบบจะตรวจสอบแต่ละเฟรมแยกกันตามข้อกำหนดของ URL และจะไม่แทรกลงในเฟรมย่อยหากไม่เป็นไปตามข้อกำหนดของ URL ค่าเริ่มต้นคือ false ซึ่งหมายความว่าระบบจะจับคู่เฉพาะเฟรมบนสุด

  • CSS

    string[] ไม่บังคับ

    รายการไฟล์ CSS ที่จะแทรกลงในหน้าเว็บที่ตรงกัน ระบบจะแทรกข้อมูลเหล่านี้ตามลำดับที่ปรากฏในอาร์เรย์นี้ ก่อนที่จะสร้างหรือแสดง DOM ใดๆ สำหรับหน้าเว็บ

  • excludeMatches

    string[] ไม่บังคับ

    ยกเว้นหน้าเว็บที่สคริปต์เนื้อหานี้จะแทรกเข้าไป ดูรายละเอียดเพิ่มเติมเกี่ยวกับไวยากรณ์ของสตริงเหล่านี้ได้ที่รูปแบบการจับคู่

  • id

    สตริง

    รหัสของ Content Script ที่ระบุในการเรียก 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

พร็อพเพอร์ตี้

  • args

    any[] ไม่บังคับ

    Chrome 92 ขึ้นไป

    อาร์กิวเมนต์ที่จะส่งไปยังฟังก์ชันที่ระบุ ซึ่งจะใช้ได้ก็ต่อเมื่อระบุพารามิเตอร์ func อาร์กิวเมนต์เหล่านี้ต้องเป็น JSON ที่ทำให้เป็นอนุกรมได้

  • ไฟล์

    string[] ไม่บังคับ

    เส้นทางของไฟล์ JS หรือ CSS ที่จะแทรก ซึ่งสัมพันธ์กับไดเรกทอรีรูทของส่วนขยาย ต้องระบุ files หรือ func อย่างใดอย่างหนึ่งเท่านั้น

  • injectImmediately

    บูลีน ไม่บังคับ

    Chrome 102 ขึ้นไป

    ควรทริกเกอร์การแทรกในเป้าหมายโดยเร็วที่สุดหรือไม่ โปรดทราบว่าการดำเนินการนี้ไม่ได้เป็นการรับประกันว่าจะมีการแทรกก่อนที่หน้าเว็บจะโหลด เนื่องจากหน้าเว็บอาจโหลดเสร็จแล้วเมื่อสคริปต์ไปถึงเป้าหมาย

  • เป้าหมาย

    รายละเอียดที่ระบุเป้าหมายที่จะแทรกสคริปต์

  • โลก

    ExecutionWorld ไม่บังคับ

    Chrome 95 ขึ้นไป

    "โลก" ของ JavaScript ที่ใช้เรียกใช้สคริปต์ ค่าเริ่มต้นคือ ISOLATED

  • func

    void optional

    Chrome 92 ขึ้นไป

    ฟังก์ชัน JavaScript ที่จะแทรก ระบบจะแปลงฟังก์ชันนี้เป็นอนุกรม แล้วจึงแปลงเป็นดีซีเรียลไลซ์เพื่อการแทรก ซึ่งหมายความว่าพารามิเตอร์ที่เชื่อมโยงและบริบทการดำเนินการจะหายไป ต้องระบุ files หรือ func อย่างใดอย่างหนึ่งเท่านั้น

    ฟังก์ชัน func มีลักษณะดังนี้

    () => {...}

StyleOrigin

แหล่งที่มาของการเปลี่ยนแปลงสไตล์ ดูข้อมูลเพิ่มเติมได้ที่แหล่งที่มาของสไตล์

ค่าแจกแจง

"AUTHOR"

"USER"

เมธอด

executeScript()

chrome.scripting.executeScript(
  injection: ScriptInjection,
)
: Promise<InjectionResult[]>

แทรกสคริปต์ลงในบริบทเป้าหมาย โดยค่าเริ่มต้น สคริปต์จะทำงานที่ document_idle หรือทันทีหากหน้าเว็บโหลดแล้ว หากตั้งค่าพร็อพเพอร์ตี้ injectImmediately สคริปต์จะแทรกโดยไม่ต้องรอ แม้ว่าหน้าจะโหลดไม่เสร็จก็ตาม หากสคริปต์ประเมินเป็น Promise เบราว์เซอร์จะรอให้ Promise เสร็จสมบูรณ์และแสดงผลค่าที่ได้

พารามิเตอร์

  • การแทรก

    รายละเอียดของสคริปต์ที่จะแทรก

การคืนสินค้า

  • Promise<InjectionResult[]>

    Chrome 90 ขึ้นไป

    ส่งคืน Promise ซึ่งจะได้รับการแก้ไขเมื่อการแทรกเสร็จสมบูรณ์ อาร์เรย์ที่ได้จะมีผลการดำเนินการสำหรับแต่ละเฟรมที่การแทรกสำเร็จ

getRegisteredContentScripts()

Chrome 96 ขึ้นไป
chrome.scripting.getRegisteredContentScripts(
  filter?: ContentScriptFilter,
)
: Promise<RegisteredContentScript[]>

แสดงผลสคริปต์เนื้อหาที่ลงทะเบียนแบบไดนามิกทั้งหมดสำหรับส่วนขยายนี้ซึ่งตรงกับตัวกรองที่ระบุ

พารามิเตอร์

  • ตัวกรอง

    ContentScriptFilter ไม่บังคับ

    ออบเจ็กต์เพื่อกรองสคริปต์ที่ลงทะเบียนแบบไดนามิกของส่วนขยาย

การคืนสินค้า

insertCSS()

chrome.scripting.insertCSS(
  injection: CSSInjection,
)
: Promise<void>

แทรกสไตล์ชีต CSS ลงในบริบทเป้าหมาย หากระบุเฟรมหลายเฟรม ระบบจะละเว้นการแทรกที่ไม่สำเร็จ

พารามิเตอร์

  • การแทรก

    รายละเอียดของสไตล์ที่จะแทรก

การคืนสินค้า

  • Promise<void>

    Chrome 90 ขึ้นไป

    ส่งคืน Promise ซึ่งจะได้รับการแก้ไขเมื่อการแทรกเสร็จสมบูรณ์

registerContentScripts()

Chrome 96 ขึ้นไป
chrome.scripting.registerContentScripts(
  scripts: RegisteredContentScript[],
)
: Promise<void>

ลงทะเบียนสคริปต์เนื้อหาอย่างน้อย 1 รายการสำหรับส่วนขยายนี้

พารามิเตอร์

  • สคริปต์

    มีรายการสคริปต์ที่จะลงทะเบียน หากมีข้อผิดพลาดระหว่างการแยกวิเคราะห์สคริปต์/การตรวจสอบไฟล์ หรือหากมีรหัสที่ระบุอยู่แล้ว ระบบจะไม่ลงทะเบียนสคริปต์

การคืนสินค้า

  • Promise<void>

    แสดงผล Promise ซึ่งจะได้รับการแก้ไขเมื่อลงทะเบียนสคริปต์ทั้งหมดแล้ว หรือปฏิเสธหากเกิดข้อผิดพลาด

removeCSS()

Chrome 90 ขึ้นไป
chrome.scripting.removeCSS(
  injection: CSSInjection,
)
: Promise<void>

นำสไตล์ชีต CSS ที่ส่วนขยายนี้แทรกไว้ก่อนหน้านี้ออกจากบริบทเป้าหมาย

พารามิเตอร์

  • การแทรก

    รายละเอียดของสไตล์ที่จะนำออก โปรดทราบว่าพร็อพเพอร์ตี้ css, files และ origin ต้องตรงกับชีตสไตล์ที่แทรกผ่าน insertCSS ทุกประการ การพยายามนำชีตสไตล์ที่ไม่มีอยู่ออกจะไม่มีผล

การคืนสินค้า

  • Promise<void>

    แสดงผล Promise ซึ่งจะได้รับการแก้ไขเมื่อการนำออกเสร็จสมบูรณ์

unregisterContentScripts()

Chrome 96 ขึ้นไป
chrome.scripting.unregisterContentScripts(
  filter?: ContentScriptFilter,
)
: Promise<void>

ยกเลิกการลงทะเบียนสคริปต์เนื้อหาสำหรับส่วนขยายนี้

พารามิเตอร์

  • ตัวกรอง

    ContentScriptFilter ไม่บังคับ

    หากระบุ ระบบจะยกเลิกการลงทะเบียนสคริปต์เนื้อหาแบบไดนามิกที่ตรงกับตัวกรองเท่านั้น มิเช่นนั้น ระบบจะยกเลิกการลงทะเบียนสคริปต์เนื้อหาแบบไดนามิกทั้งหมดของส่วนขยาย

การคืนสินค้า

  • Promise<void>

    แสดงผล Promise ซึ่งจะได้รับการแก้ไขเมื่อยกเลิกการลงทะเบียนสคริปต์แล้ว หรือปฏิเสธหากเกิดข้อผิดพลาด

updateContentScripts()

Chrome 96 ขึ้นไป
chrome.scripting.updateContentScripts(
  scripts: RegisteredContentScript[],
)
: Promise<void>

อัปเดต Content Script อย่างน้อย 1 รายการสำหรับส่วนขยายนี้

พารามิเตอร์

  • สคริปต์

    มีรายการสคริปต์ที่จะอัปเดต ระบบจะอัปเดตพร็อพเพอร์ตี้สำหรับสคริปต์ที่มีอยู่ก็ต่อเมื่อมีการระบุในออบเจ็กต์นี้ หากมีข้อผิดพลาดระหว่างการแยกวิเคราะห์สคริปต์/การตรวจสอบไฟล์ หรือหากรหัสที่ระบุไม่ตรงกับสคริปต์ที่ลงทะเบียนอย่างสมบูรณ์ ระบบจะไม่ทำการอัปเดตสคริปต์

การคืนสินค้า

  • Promise<void>

    แสดงผล Promise ซึ่งจะได้รับการแก้ไขเมื่ออัปเดตสคริปต์แล้ว หรือปฏิเสธหากเกิดข้อผิดพลาด