คำอธิบาย
ใช้ userScripts
API เพื่อเรียกใช้สคริปต์ของผู้ใช้ในบริบทของสคริปต์ของผู้ใช้
สิทธิ์
userScripts
หากต้องการใช้ User Scripts API chrome.userScripts
ให้เพิ่มสิทธิ์ "userScripts"
ลงใน manifest.json และ "host_permissions"
สำหรับเว็บไซต์ที่คุณต้องการเรียกใช้สคริปต์
{ "name": "User script test extension", "manifest_version": 3, "minimum_chrome_version": "120", "permissions": [ "userScripts" ], "host_permissions": [ "*://example.com/*" ] }
ความพร้อมใช้งาน
แนวคิดและการใช้งาน
สคริปต์ผู้ใช้คือข้อมูลโค้ดที่แทรกลงในหน้าเว็บเพื่อแก้ไขลักษณะที่ปรากฏหรือลักษณะการทำงานของหน้าเว็บ User Scripts API ช่วยให้คุณเรียกใช้โค้ดที่กำหนดเองได้ ซึ่งแตกต่างจากฟีเจอร์ส่วนขยายอื่นๆ เช่น Content Scripts และ chrome.scripting
API API นี้จำเป็นสำหรับส่วนขยายที่เรียกใช้สคริปต์ที่ผู้ใช้ระบุซึ่งไม่สามารถจัดส่งเป็นส่วนหนึ่งของแพ็กเกจส่วนขยายได้
เปิดใช้การใช้ API userScripts
หลังจากส่วนขยายได้รับสิทธิ์ในการใช้ userScripts API แล้ว ผู้ใช้ ต้องเปิดใช้ปุ่มสลับที่เฉพาะเจาะจงเพื่อให้ส่วนขยายของคุณใช้ API ได้ สวิตช์เฉพาะที่จำเป็นและลักษณะการทำงานของ API เมื่อปิดใช้จะแตกต่างกันไปตามเวอร์ชันของ Chrome
ใช้การตรวจสอบต่อไปนี้เพื่อพิจารณาว่าผู้ใช้ต้องเปิดใช้ปุ่มสลับใด เช่น ในระหว่างการเริ่มต้นใช้งานผู้ใช้ใหม่
let version = Number(navigator.userAgent.match(/(Chrome|Chromium)\/([0-9]+)/)?.[2]); if (version >= 138) { // Allow User Scripts toggle will be used. } else { // Developer mode toggle will be used. }
ส่วนต่อไปนี้จะอธิบายการเปิด/ปิดต่างๆ และวิธีเปิดใช้
Chrome เวอร์ชันก่อน 138 (สลับโหมดนักพัฒนาซอฟต์แวร์)
ในฐานะนักพัฒนาส่วนขยาย คุณได้เปิดใช้โหมดนักพัฒนาซอฟต์แวร์ ในการติดตั้ง Chrome แล้ว ผู้ใช้ ต้องเปิดใช้โหมดนักพัฒนาซอฟต์แวร์ด้วย
คุณสามารถคัดลอกและวาง วิธีการต่อไปนี้ลงในเอกสารประกอบของส่วนขยายสำหรับผู้ใช้
- ไปที่หน้าส่วนขยายโดยป้อน
chrome://extensions
ในแท็บใหม่ (chrome://
URL ออกแบบมาให้ลิงก์ไม่ได้) เปิดใช้โหมดนักพัฒนาซอฟต์แวร์โดยคลิกสวิตช์เปิด/ปิดข้างโหมดนักพัฒนาซอฟต์แวร์
หน้าส่วนขยาย (chrome://extensions)
Chrome เวอร์ชัน 138 ขึ้นไป (ปุ่มเปิด/ปิด "อนุญาตสคริปต์ของผู้ใช้")
ปุ่มเปิด/ปิดอนุญาตสคริปต์ของผู้ใช้จะอยู่ในหน้า รายละเอียดของส่วนขยายแต่ละรายการ (เช่น chrome://extensions/?id=YOUR_EXTENSION_ID)
คุณสามารถคัดลอกและวางวิธีการต่อไปนี้ ลงในเอกสารประกอบของส่วนขยายสำหรับผู้ใช้
- ไปที่หน้าส่วนขยายโดยป้อน
chrome://extensions
ในแท็บใหม่ (chrome://
URL ออกแบบมาให้ลิงก์ไม่ได้) - คลิกปุ่ม "รายละเอียด" ในการ์ดส่วนขยายเพื่อดูข้อมูลโดยละเอียดเกี่ยวกับส่วนขยาย
- คลิกสวิตช์เปิด/ปิดข้างอนุญาตสคริปต์ของผู้ใช้

ตรวจสอบความพร้อมใช้งานของ API
เราขอแนะนำให้คุณตรวจสอบต่อไปนี้เพื่อดูว่าได้เปิดใช้ UserScripts API หรือไม่ เนื่องจาก API นี้ทำงานได้ใน Chrome ทุกเวอร์ชัน การตรวจสอบนี้พยายามเรียกใช้เมธอด chrome.userScripts()
ซึ่งควรจะสำเร็จเสมอเมื่อ API พร้อมใช้งาน หากการเรียกนี้แสดงข้อผิดพลาด แสดงว่า API ไม่พร้อมใช้งาน
function isUserScriptsAvailable() { try { // Method call which throws if API permission or toggle is not enabled. chrome.userScripts.getScripts(); return true; } catch { // Not available. return false; } }
ทำงานในโลกที่แยกจากกัน
ทั้งสคริปต์ผู้ใช้และสคริปต์เนื้อหาสามารถทำงานในโลกที่แยกจากกันหรือในโลกหลักได้ โลกที่แยกจากกันคือสภาพแวดล้อมการดำเนินการที่โฮสต์เพจหรือส่วนขยายอื่นๆ เข้าถึงไม่ได้ ซึ่งช่วยให้สคริปต์ของผู้ใช้เปลี่ยนสภาพแวดล้อม JavaScript ได้โดยไม่ส่งผลกระทบต่อหน้าโฮสต์หรือสคริปต์ของผู้ใช้และสคริปต์เนื้อหาของส่วนขยายอื่นๆ ในทางกลับกัน สคริปต์ของผู้ใช้ (และ Content Script) จะไม่ปรากฏในหน้าโฮสต์หรือต่อผู้ใช้และ Content Script ของส่วนขยายอื่นๆ สคริปต์ที่ทำงานในโลกหลักจะเข้าถึงได้ในหน้าโฮสต์และส่วนขยายอื่นๆ และจะแสดงต่อหน้าโฮสต์และส่วนขยายอื่นๆ หากต้องการเลือกโลก ให้ส่ง "USER_SCRIPT"
หรือ "MAIN"
เมื่อโทรหา userScripts.register()
หากต้องการกำหนดค่านโยบายความปลอดภัยของเนื้อหาสำหรับโลกของ USER_SCRIPT
ให้เรียกใช้ userScripts.configureWorld()
ดังนี้
chrome.userScripts.configureWorld({ csp: "script-src 'self'" });
การรับส่งข้อความ
เช่นเดียวกับ Content Script และเอกสารนอกหน้าจอ User Script จะสื่อสารกับส่วนอื่นๆ ของส่วนขยายโดยใช้การรับส่งข้อความ (ซึ่งหมายความว่า User Script สามารถเรียกใช้ runtime.sendMessage()
และ runtime.connect()
ได้เหมือนกับส่วนอื่นๆ ของส่วนขยาย) แต่จะได้รับโดยใช้ตัวแฮนเดิลเหตุการณ์เฉพาะ (หมายความว่าจะไม่ใช้ onMessage
หรือ onConnect
) ตัวแฮนเดิลเหล่านี้เรียกว่า runtime.onUserScriptMessage
และ runtime.onUserScriptConnect
แฮนเดิลที่เฉพาะเจาะจงช่วยให้ระบุข้อความจากสคริปต์ของผู้ใช้ได้ง่ายขึ้น ซึ่งเป็นบริบทที่เชื่อถือได้น้อยกว่า
ก่อนส่งข้อความ คุณต้องเรียกใช้ configureWorld()
โดยตั้งค่าอาร์กิวเมนต์ messaging
เป็น true
โปรดทราบว่าคุณส่งอาร์กิวเมนต์ csp
และ messaging
พร้อมกันได้
chrome.userScripts.configureWorld({ messaging: true });
การอัปเดตส่วนขยาย
ระบบจะล้างสคริปต์ของผู้ใช้เมื่อส่วนขยายอัปเดต คุณเพิ่มกลับได้โดยการเรียกใช้โค้ดในตัวแฮนเดิลเหตุการณ์ runtime.onInstalled
ใน Service Worker ของส่วนขยาย ตอบกลับเฉพาะ"update"
เหตุผลที่ส่งไปยังการเรียกกลับของเหตุการณ์
ตัวอย่าง
ตัวอย่างนี้มาจากตัวอย่าง userScript ในที่เก็บตัวอย่างของเรา
ลงทะเบียนสคริปต์
ตัวอย่างต่อไปนี้แสดงการเรียกใช้ register()
พื้นฐาน อาร์กิวเมนต์แรกคืออาร์เรย์ของออบเจ็กต์ที่กำหนดสคริปต์ที่จะลงทะเบียน คุณมีตัวเลือกมากกว่าที่แสดงที่นี่
chrome.userScripts.register([{ id: 'test', matches: ['*://*/*'], js: [{code: 'alert("Hi!")'}] }]);
ประเภท
ExecutionWorld
โลกของ JavaScript สำหรับสคริปต์ผู้ใช้ที่จะดำเนินการภายใน
ค่าแจกแจง
"MAIN"
ระบุสภาพแวดล้อมการดำเนินการของ DOM ซึ่งเป็นสภาพแวดล้อมการดำเนินการที่แชร์กับ JavaScript ของหน้าโฮสต์
"USER_SCRIPT"
ระบุสภาพแวดล้อมการดำเนินการที่เฉพาะเจาะจงสำหรับสคริปต์ของผู้ใช้และได้รับการยกเว้นจาก CSP ของหน้าเว็บ
InjectionResult
พร็อพเพอร์ตี้
- documentId
สตริง
เอกสารที่เชื่อมโยงกับการแทรก
- ข้อผิดพลาด
สตริง ไม่บังคับ
ข้อผิดพลาด (หากมี)
error
และresult
จะเป็นข้อมูลแยกกัน - frameId
ตัวเลข
เฟรมที่เชื่อมโยงกับการแทรก
- ผลลัพธ์
ไม่บังคับ
ผลลัพธ์ของการเรียกใช้สคริปต์
InjectionTarget
พร็อพเพอร์ตี้
- allFrames
บูลีน ไม่บังคับ
เลือกว่าสคริปต์ควรแทรกในเฟรมทั้งหมดภายในแท็บหรือไม่ ค่าเริ่มต้นคือ false ค่านี้ต้องเป็นเท็จหากมีการระบุ
frameIds
- documentIds
string[] ไม่บังคับ
รหัสของ documentId ที่เฉพาะเจาะจงที่จะแทรก ห้ามตั้งค่านี้หากตั้งค่า
frameIds
ไว้ - frameIds
number[] ไม่บังคับ
รหัสของเฟรมที่เฉพาะเจาะจงที่จะแทรก
- tabId
ตัวเลข
รหัสของแท็บที่จะแทรก
RegisteredUserScript
พร็อพเพอร์ตี้
- allFrames
บูลีน ไม่บังคับ
หากเป็นจริง ระบบจะแทรกลงในทุกเฟรม แม้ว่าเฟรมจะไม่ใช่เฟรมบนสุดในแท็บก็ตาม แต่ละเฟรมจะได้รับการตรวจสอบแยกกันตามข้อกำหนดของ URL และจะไม่แทรกลงในเฟรมย่อยหากไม่เป็นไปตามข้อกำหนดของ URL ค่าเริ่มต้นเป็น false ซึ่งหมายความว่าจะมีการจับคู่เฉพาะเฟรมบนสุด
- excludeGlobs
string[] ไม่บังคับ
ระบุรูปแบบไวลด์การ์ดสำหรับหน้าเว็บที่จะไม่แทรกสคริปต์ผู้ใช้นี้
- excludeMatches
string[] ไม่บังคับ
ยกเว้นหน้าเว็บที่สคริปต์ผู้ใช้นี้จะแทรก ดูรายละเอียดเพิ่มเติมเกี่ยวกับไวยากรณ์ของสตริงเหล่านี้ได้ที่รูปแบบการจับคู่
- id
สตริง
รหัสของสคริปต์ผู้ใช้ที่ระบุในการเรียก API พร็อพเพอร์ตี้นี้ต้องไม่ขึ้นต้นด้วย "_" เนื่องจากสงวนไว้เป็นคำนำหน้าสำหรับรหัสสคริปต์ที่สร้างขึ้น
- includeGlobs
string[] ไม่บังคับ
ระบุรูปแบบไวลด์การ์ดสำหรับหน้าเว็บที่จะแทรกสคริปต์ผู้ใช้นี้
- js
ScriptSource[] ไม่บังคับ
รายการออบเจ็กต์ ScriptSource ที่กำหนดแหล่งที่มาของสคริปต์ที่จะแทรกลงในหน้าที่ตรงกัน คุณต้องระบุพร็อพเพอร์ตี้นี้สำหรับ ${ref:register} และเมื่อระบุแล้ว พร็อพเพอร์ตี้นี้ต้องเป็นอาร์เรย์ที่ไม่ว่าง
- ตรงกับ
string[] ไม่บังคับ
ระบุหน้าเว็บที่จะแทรกสคริปต์ของผู้ใช้นี้ ดูรายละเอียดเพิ่มเติมเกี่ยวกับไวยากรณ์ของสตริงเหล่านี้ได้ที่รูปแบบการจับคู่ ต้องระบุพร็อพเพอร์ตี้นี้สำหรับ ${ref:register}
- runAt
RunAt ไม่บังคับ
ระบุเวลาที่แทรกไฟล์ JavaScript ลงในหน้าเว็บ ค่าที่ต้องการและค่าเริ่มต้นคือ
document_idle
- โลก
ExecutionWorld ไม่บังคับ
สภาพแวดล้อมการดำเนินการ JavaScript เพื่อเรียกใช้สคริปต์ โดยมีค่าเริ่มต้นเป็น
`USER_SCRIPT`
- worldId
สตริง ไม่บังคับ
Chrome 133 ขึ้นไประบุรหัสโลกของสคริปต์ผู้ใช้ที่จะเรียกใช้ หากละไว้ สคริปต์จะทำงานในโลกสคริปต์ของผู้ใช้เริ่มต้น ใช้ได้เมื่อละเว้น
world
หรือเป็นUSER_SCRIPT
เท่านั้น ค่าที่มีขีดล่างนำหน้า (_
) จะสงวนไว้
ScriptSource
พร็อพเพอร์ตี้
- รหัส
สตริง ไม่บังคับ
สตริงที่มีโค้ด JavaScript ที่จะแทรก ต้องระบุ
file
หรือcode
อย่างใดอย่างหนึ่งเท่านั้น - ไฟล์
สตริง ไม่บังคับ
เส้นทางของไฟล์ JavaScript ที่จะแทรกซึ่งสัมพันธ์กับไดเรกทอรีรากของส่วนขยาย ต้องระบุ
file
หรือcode
อย่างใดอย่างหนึ่งเท่านั้น
UserScriptFilter
พร็อพเพอร์ตี้
- รหัส
string[] ไม่บังคับ
getScripts
จะแสดงเฉพาะสคริปต์ที่มีรหัสที่ระบุในรายการนี้
UserScriptInjection
พร็อพเพอร์ตี้
- injectImmediately
บูลีน ไม่บังคับ
ควรกระตุ้นการแทรกในเป้าหมายโดยเร็วที่สุดหรือไม่ โปรดทราบว่าการดำเนินการนี้ไม่ได้รับประกันว่าจะมีการแทรกก่อนที่หน้าเว็บจะโหลด เนื่องจากหน้าเว็บอาจโหลดเสร็จแล้วเมื่อสคริปต์ไปถึงเป้าหมาย
- js
รายการออบเจ็กต์ ScriptSource ที่กำหนดแหล่งที่มาของสคริปต์ที่จะแทรกลงในเป้าหมาย
- เป้าหมาย
รายละเอียดที่ระบุเป้าหมายที่จะแทรกสคริปต์
- โลก
ExecutionWorld ไม่บังคับ
"โลก" ของ JavaScript ที่จะใช้เรียกใช้สคริปต์ โดยมีค่าเริ่มต้นเป็น
USER_SCRIPT
- worldId
สตริง ไม่บังคับ
ระบุรหัสโลกของสคริปต์ผู้ใช้ที่จะเรียกใช้ หากละไว้ สคริปต์จะทำงานในโลกสคริปต์ของผู้ใช้เริ่มต้น ใช้ได้เมื่อละเว้น
world
หรือเป็นUSER_SCRIPT
เท่านั้น ค่าที่มีขีดล่างนำหน้า (_
) จะสงวนไว้
WorldProperties
พร็อพเพอร์ตี้
- csp
สตริง ไม่บังคับ
ระบุ CSP ทั่วโลก ค่าเริ่มต้นคือ
`ISOLATED`
world csp - ส่งข้อความ
บูลีน ไม่บังคับ
ระบุว่าจะแสดง API การรับส่งข้อความหรือไม่ โดยมีค่าเริ่มต้นเป็น
false
- worldId
สตริง ไม่บังคับ
Chrome 133 ขึ้นไประบุรหัสของโลกสคริปต์ผู้ใช้ที่ต้องการอัปเดต หากไม่ได้ระบุไว้ จะอัปเดตพร็อพเพอร์ตี้ของโลกสคริปต์ผู้ใช้เริ่มต้น ค่าที่มีขีดล่างนำหน้า (
_
) จะสงวนไว้
เมธอด
configureWorld()
chrome.userScripts.configureWorld(
properties: WorldProperties,
): Promise<void>
กำหนดค่า`USER_SCRIPT`
สภาพแวดล้อมการดำเนินการ
พารามิเตอร์
- พร็อพเพอร์ตี้
มีการกำหนดค่าโลกของสคริปต์ผู้ใช้
การคืนสินค้า
-
Promise<void>
execute()
chrome.userScripts.execute(
injection: UserScriptInjection,
): Promise<InjectionResult[]>
แทรกสคริปต์ลงในบริบทเป้าหมาย โดยค่าเริ่มต้น สคริปต์จะทำงานที่ document_idle
หรือทันทีหากหน้าเว็บโหลดแล้ว หากตั้งค่าพร็อพเพอร์ตี้ injectImmediately
ไว้ สคริปต์จะแทรกโดยไม่ต้องรอ แม้ว่าหน้าจะโหลดไม่เสร็จก็ตาม หากสคริปต์ประเมินเป็น Promise เบราว์เซอร์จะรอให้ Promise เสร็จสมบูรณ์และแสดงผลค่าที่ได้
พารามิเตอร์
- การแทรก
การคืนสินค้า
-
Promise<InjectionResult[]>
getScripts()
chrome.userScripts.getScripts(
filter?: UserScriptFilter,
): Promise<RegisteredUserScript[]>
แสดงผลสคริปต์ของผู้ใช้ที่ลงทะเบียนแบบไดนามิกทั้งหมดสำหรับส่วนขยายนี้
พารามิเตอร์
- ตัวกรอง
UserScriptFilter ไม่บังคับ
หากระบุไว้ เมธอดนี้จะแสดงเฉพาะสคริปต์ของผู้ใช้ที่ตรงกัน
การคืนสินค้า
-
Promise<RegisteredUserScript[]>
getWorldConfigurations()
chrome.userScripts.getWorldConfigurations(): Promise<WorldProperties[]>
ดึงข้อมูลการกำหนดค่าโลกที่ลงทะเบียนทั้งหมด
การคืนสินค้า
-
Promise<WorldProperties[]>
register()
chrome.userScripts.register(
scripts: RegisteredUserScript[],
): Promise<void>
ลงทะเบียนสคริปต์ของผู้ใช้อย่างน้อย 1 รายการสำหรับส่วนขยายนี้
พารามิเตอร์
- สคริปต์
มีรายการสคริปต์ของผู้ใช้ที่จะลงทะเบียน
การคืนสินค้า
-
Promise<void>
resetWorldConfiguration()
chrome.userScripts.resetWorldConfiguration(
worldId?: string,
): Promise<void>
รีเซ็ตการกำหนดค่าสำหรับโลกของสคริปต์ของผู้ใช้ สคริปต์ที่แทรกลงในเวิลด์ด้วยรหัสที่ระบุจะใช้การกำหนดค่าเวิลด์เริ่มต้น
พารามิเตอร์
- worldId
สตริง ไม่บังคับ
รหัสของโลกสคริปต์ผู้ใช้ที่จะรีเซ็ต หากละไว้ จะรีเซ็ตการกำหนดค่าเริ่มต้นของโลก
การคืนสินค้า
-
Promise<void>
unregister()
chrome.userScripts.unregister(
filter?: UserScriptFilter,
): Promise<void>
ยกเลิกการลงทะเบียนสคริปต์ของผู้ใช้ที่ลงทะเบียนแบบไดนามิกทั้งหมดสำหรับส่วนขยายนี้
พารามิเตอร์
- ตัวกรอง
UserScriptFilter ไม่บังคับ
หากระบุไว้ เมธอดนี้จะยกเลิกการลงทะเบียนเฉพาะสคริปต์ของผู้ใช้ที่ตรงกัน
การคืนสินค้า
-
Promise<void>
update()
chrome.userScripts.update(
scripts: RegisteredUserScript[],
): Promise<void>
อัปเดตสคริปต์ของผู้ใช้อย่างน้อย 1 รายการสำหรับส่วนขยายนี้
พารามิเตอร์
- สคริปต์
มีรายการสคริปต์ของผู้ใช้ที่จะอัปเดต ระบบจะอัปเดตพร็อพเพอร์ตี้สำหรับสคริปต์ที่มีอยู่ก็ต่อเมื่อมีการระบุในออบเจ็กต์นี้ หากมีข้อผิดพลาดระหว่างการแยกวิเคราะห์สคริปต์/การตรวจสอบไฟล์ หรือหากรหัสที่ระบุไม่ตรงกับสคริปต์ที่ลงทะเบียนอย่างสมบูรณ์ ระบบจะไม่ทำการอัปเดตสคริปต์
การคืนสินค้า
-
Promise<void>