ภาพรวม
ส่วนขยายเครื่องมือสำหรับนักพัฒนาเว็บจะเพิ่มฟังก์ชันการทำงานให้กับเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome สามารถเพิ่มแผง UI ใหม่และ แถบด้านข้าง โต้ตอบกับหน้าที่ตรวจสอบ รับข้อมูลเกี่ยวกับคำขอเครือข่าย และอื่นๆ ดู ส่วนขยายเด่นสำหรับเครื่องมือสำหรับนักพัฒนาเว็บ ส่วนขยายเครื่องมือสำหรับนักพัฒนาเว็บมีสิทธิ์เข้าถึงชุดเพิ่มเติม API ส่วนขยายเฉพาะสำหรับเครื่องมือสำหรับนักพัฒนาเว็บ:
ส่วนขยายเครื่องมือสำหรับนักพัฒนาเว็บมีโครงสร้างเหมือนกับส่วนขยายอื่นๆ โดยอาจมีหน้าพื้นหลัง เนื้อหา สคริปต์ และรายการอื่นๆ นอกจากนี้ ส่วนขยายเครื่องมือสำหรับนักพัฒนาเว็บแต่ละรายการจะมีหน้าเครื่องมือสำหรับนักพัฒนาเว็บ ซึ่งสามารถเข้าถึง API ของเครื่องมือสำหรับนักพัฒนาเว็บ
หน้าเครื่องมือสำหรับนักพัฒนาเว็บ
จะมีการสร้างอินสแตนซ์หน้าเครื่องมือสำหรับนักพัฒนาเว็บของส่วนขยายทุกครั้งที่เปิดหน้าต่างเครื่องมือสำหรับนักพัฒนาเว็บ หน้าเครื่องมือสำหรับนักพัฒนาเว็บจะมีอยู่ตลอดอายุของหน้าต่างเครื่องมือสำหรับนักพัฒนาเว็บ หน้าเครื่องมือสำหรับนักพัฒนาเว็บมีสิทธิ์เข้าถึง API เครื่องมือสำหรับนักพัฒนาเว็บและ API ส่วนขยายจำนวนหนึ่ง โดยเฉพาะอย่างยิ่ง หน้าเครื่องมือสำหรับนักพัฒนาเว็บจะทำสิ่งต่อไปนี้ได้
- สร้างและโต้ตอบกับแผงโดยใช้
devtools.panels
API - รับข้อมูลเกี่ยวกับหน้าต่างที่ตรวจสอบแล้วและประเมินโค้ดในหน้าต่างที่ตรวจสอบโดยใช้
devtools.inspectedWindow
API - รับข้อมูลเกี่ยวกับคำขอเครือข่ายโดยใช้
devtools.network
API
หน้าเครื่องมือสำหรับนักพัฒนาเว็บใช้ API ส่วนขยายส่วนใหญ่โดยตรงไม่ได้ มีสิทธิ์เข้าถึงส่วนย่อยเดียวกัน
ของ API ของ extension
และ runtime
ที่สคริปต์เนื้อหามีสิทธิ์เข้าถึง กดชอบเนื้อหา
หน้าเครื่องมือสำหรับนักพัฒนาเว็บจะสื่อสารกับหน้าพื้นหลังโดยใช้ Message Passing ได้ สำหรับ
ตัวอย่างเช่น โปรดดูการแทรกสคริปต์เนื้อหา
การสร้างส่วนขยายเครื่องมือสำหรับนักพัฒนาเว็บ
หากต้องการสร้างหน้าเครื่องมือสำหรับนักพัฒนาเว็บสำหรับส่วนขยาย ให้เพิ่มช่อง devtools_page
ในส่วนขยาย
ไฟล์ Manifest:
{
"name": ...
"version": "1.0",
"minimum_chrome_version": "10.0",
"devtools_page": "devtools.html",
...
}
ระบบสร้างอินสแตนซ์ของ devtools_page
ที่ระบุในไฟล์ Manifest ของส่วนขยายสำหรับทุกๆ
หน้าต่างเครื่องมือสำหรับนักพัฒนาเว็บเปิดอยู่ หน้านี้อาจเพิ่มหน้าส่วนขยายอื่นๆ เป็นแผงและแถบด้านข้างไปยัง
หน้าต่างเครื่องมือสำหรับนักพัฒนาเว็บที่ใช้ devtools.panels
API
โมดูล API chrome.devtools.*
ใช้ได้กับหน้าที่โหลดภายในเครื่องมือสำหรับนักพัฒนาเว็บเท่านั้น
สคริปต์เนื้อหาและหน้าส่วนขยายอื่นๆ ไม่มี API เหล่านี้ ดังนั้น API
จะใช้ได้ตลอดอายุของหน้าต่างเครื่องมือสำหรับนักพัฒนาเว็บเท่านั้น
นอกจากนี้ ยังมี API เครื่องมือสำหรับนักพัฒนาเว็บบางส่วนที่ยังอยู่ระหว่างการทดสอบ โปรดดูที่ chrome.experimental* API สำหรับรายการ API ทดลองและหลักเกณฑ์เกี่ยวกับวิธีการใช้งาน
องค์ประกอบ UI ของเครื่องมือสำหรับนักพัฒนาเว็บ: แผงและแผงแถบด้านข้าง
นอกเหนือจากองค์ประกอบ UI ของส่วนขยายตามปกติ เช่น การทำงานของเบราว์เซอร์ เมนูตามบริบท และป๊อปอัป ส่วนขยายเครื่องมือสำหรับนักพัฒนาเว็บสามารถเพิ่มองค์ประกอบ UI ลงในหน้าต่างเครื่องมือสำหรับนักพัฒนาเว็บได้โดยทำดังนี้
- แผงคือแท็บระดับบนสุด เช่น แผงองค์ประกอบ แหล่งที่มา และเครือข่าย
- แผงแถบด้านข้างจะแสดง UI เสริมที่เกี่ยวข้องกับแผง รูปแบบ รูปแบบที่คำนวณ และ แผง Listener เหตุการณ์บนแผงองค์ประกอบเป็นตัวอย่างของแผงแถบด้านข้าง (โปรดทราบว่า ลักษณะของแผงแถบด้านข้างอาจไม่ตรงกับรูปภาพ ทั้งนี้ขึ้นอยู่กับเวอร์ชัน Chrome ที่คุณใช้ ที่ใช้ และตำแหน่งของหน้าต่างเครื่องมือสำหรับนักพัฒนาเว็บ)
แต่ละแผงเป็นไฟล์ HTML ของตัวเอง ซึ่งอาจมีทรัพยากรอื่นๆ (JavaScript, CSS, รูปภาพ เป็นต้น เปิด) การสร้างแผงพื้นฐานจะมีลักษณะดังนี้
chrome.devtools.panels.create("My Panel",
"MyPanelIcon.png",
"Panel.html",
function(panel) {
// code invoked on panel creation
}
);
JavaScript ที่เรียกใช้ในแผงหรือแผงแถบด้านข้างจะมีสิทธิ์เข้าถึง API เดียวกับหน้าเครื่องมือสำหรับนักพัฒนาเว็บ
การสร้างแผงแถบด้านข้างพื้นฐานสำหรับแผงองค์ประกอบจะมีลักษณะดังนี้
chrome.devtools.panels.elements.createSidebarPane("My Sidebar",
function(sidebar) {
// sidebar initialization code here
sidebar.setObject({ some_data: "Some data to show" });
});
การแสดงเนื้อหาในหน้าต่างแถบด้านข้างมีหลายวิธีดังนี้
- เนื้อหา HTML เรียกใช้
setPage
เพื่อระบุหน้า HTML ที่จะแสดงในแผง - ข้อมูล JSON ส่งออบเจ็กต์ JSON ไปยัง
setObject
- นิพจน์ JavaScript ส่งผ่านนิพจน์ไปยัง
setExpression
เครื่องมือสำหรับนักพัฒนาเว็บจะประเมิน ในบริบทของหน้าเว็บที่ตรวจสอบ และแสดงค่าที่ส่งกลับ
สำหรับทั้ง setObject
และ setExpression
แผงจะแสดงค่าตามที่จะปรากฏในคอลัมน์
คอนโซลเครื่องมือสำหรับนักพัฒนาเว็บ แต่ setExpression
ให้คุณแสดงองค์ประกอบ DOM และ JavaScript ที่กำหนดเองได้
แต่ setObject
รองรับเฉพาะออบเจ็กต์ JSON เท่านั้น
การสื่อสารระหว่างคอมโพเนนต์ส่วนขยาย
ส่วนต่อไปนี้จะอธิบายสถานการณ์ทั่วไปสำหรับการสื่อสารระหว่าง คอมโพเนนต์ของส่วนขยายเครื่องมือสำหรับนักพัฒนาเว็บ
การแทรกสคริปต์เนื้อหา
หน้าเครื่องมือสำหรับนักพัฒนาเว็บเรียกใช้ tabs.executeScript
โดยตรงไม่ได้ หากต้องการแทรกสคริปต์เนื้อหาจาก
ในหน้าเครื่องมือสำหรับนักพัฒนาเว็บ คุณต้องดึงรหัสของแท็บของหน้าต่างที่ตรวจสอบโดยใช้
inspectedWindow.tabId
และส่งข้อความไปยังหน้าเว็บพื้นหลัง จาก
ในหน้าพื้นหลัง ให้เรียก tabs.executeScript
เพื่อแทรกสคริปต์
ข้อมูลโค้ดต่อไปนี้แสดงวิธีแทรกสคริปต์เนื้อหาโดยใช้ executeScript
// DevTools page -- devtools.js
// Create a connection to the background page
var backgroundPageConnection = chrome.runtime.connect({
name: "devtools-page"
});
backgroundPageConnection.onMessage.addListener(function (message) {
// Handle responses from the background page, if any
});
// Relay the tab ID to the background page
chrome.runtime.sendMessage({
tabId: chrome.devtools.inspectedWindow.tabId,
scriptToInject: "content_script.js"
});
โค้ดสำหรับหน้าพื้นหลัง:
// Background page -- background.js
chrome.runtime.onConnect.addListener(function(devToolsConnection) {
// assign the listener function to a variable so we can remove it later
var devToolsListener = function(message, sender, sendResponse) {
// Inject a content script into the identified tab
chrome.tabs.executeScript(message.tabId,
{ file: message.scriptToInject });
}
// add the listener
devToolsConnection.onMessage.addListener(devToolsListener);
devToolsConnection.onDisconnect.addListener(function() {
devToolsConnection.onMessage.removeListener(devToolsListener);
});
});
การประเมิน JavaScript ในหน้าต่างที่ตรวจสอบ
คุณสามารถใช้เมธอด inspectedWindow.eval
เพื่อเรียกใช้โค้ด JavaScript ในบริบทของ
หน้าเว็บที่ตรวจสอบ คุณเรียกใช้เมธอด eval
ได้จากหน้าเครื่องมือสำหรับนักพัฒนาเว็บ แผง หรือแผงแถบด้านข้าง
โดยค่าเริ่มต้น นิพจน์จะได้รับการประเมินในบริบทของเฟรมหลักของหน้า ตอนนี้คุณสามารถ
ทำความคุ้นเคยกับฟีเจอร์ commandline API ของเครื่องมือสำหรับนักพัฒนาเว็บ เช่น การตรวจสอบองค์ประกอบ
(inspect(elem)
) ทำลายฟังก์ชัน (debug(fn)
) คัดลอกไปยังคลิปบอร์ด (copy()
) และอื่นๆ
inspectedWindow.eval()
ใช้บริบทและตัวเลือกการเรียกใช้สคริปต์เหมือนกับโค้ดที่พิมพ์ที่
คอนโซลเครื่องมือสำหรับนักพัฒนาเว็บซึ่งอนุญาตการเข้าถึง API เหล่านี้ภายในระยะเวลาการประเมิน ตัวอย่างเช่น SOAK จะใช้พารามิเตอร์นี้
สำหรับการตรวจสอบองค์ประกอบ
chrome.devtools.inspectedWindow.eval(
"inspect($$('head script[data-soak=main]')[0])",
function(result, isException) { }
);
หรือใช้ตัวเลือก useContentScriptContext: true
กับ inspectedWindow.eval()
เพื่อ
ประเมินนิพจน์ในบริบทเดียวกับสคริปต์เนื้อหา กำลังโทรหา eval
ด้วย
useContentScriptContext: true
จะไม่สร้างบริบทสคริปต์เนื้อหา คุณจึงต้องโหลด
สคริปต์บริบทก่อนเรียกใช้ eval
โดยการเรียกใช้ executeScript
หรือระบุเนื้อหา
ในไฟล์ manifest.json
เมื่อมีบริบทของสคริปต์บริบทแล้ว คุณสามารถใช้ตัวเลือกนี้เพื่อแทรกเนื้อหาเพิ่มเติม สคริปต์
เมธอด eval
มีประสิทธิภาพเมื่อใช้ในบริบทที่เหมาะสมและเป็นอันตรายเมื่อใช้
อย่างไม่เหมาะสม ให้ใช้เมธอด tabs.executeScript
หากไม่จําเป็นต้องเข้าถึง
บริบท JavaScript ของหน้าที่ตรวจสอบ สำหรับข้อควรระวังโดยละเอียดและการเปรียบเทียบทั้ง 2 วิธีนี้
ดู inspectedWindow
การส่งผ่านองค์ประกอบที่เลือกไปยังสคริปต์เนื้อหา
สคริปต์เนื้อหาไม่มีสิทธิ์เข้าถึงองค์ประกอบที่เลือกในปัจจุบันโดยตรง อย่างไรก็ตาม โค้ดที่คุณ
ดำเนินการโดยใช้ inspectedWindow.eval
มีสิทธิ์เข้าถึงคอนโซลเครื่องมือสำหรับนักพัฒนาเว็บและ API บรรทัดคำสั่ง
เช่น ในโค้ดที่ประเมิน คุณจะใช้ $0
เพื่อเข้าถึงองค์ประกอบที่เลือกได้
วิธีส่งองค์ประกอบที่เลือกไปยังสคริปต์เนื้อหา
- สร้างเมธอดในสคริปต์เนื้อหาเพื่อนำองค์ประกอบที่เลือกเป็นอาร์กิวเมนต์
- เรียกใช้เมธอดจากหน้าเครื่องมือสำหรับนักพัฒนาเว็บโดยใช้
inspectedWindow.eval
ที่มีเมธอด ตัวเลือกuseContentScriptContext: true
โค้ดในสคริปต์เนื้อหาอาจมีลักษณะดังนี้
function setSelectedElement(el) {
// do something with the selected element
}
เรียกใช้เมธอดจากหน้าเครื่องมือสำหรับนักพัฒนาเว็บดังนี้
chrome.devtools.inspectedWindow.eval("setSelectedElement($0)",
{ useContentScriptContext: true });
ตัวเลือก useContentScriptContext: true
ระบุว่าต้องมีการประเมินนิพจน์ใน
บริบทเดียวกับสคริปต์เนื้อหา เพื่อให้สามารถเข้าถึงเมธอด setSelectedElement
การรับ window
ของแผงอ้างอิง
หากต้องการ postMessage
จากแผงเครื่องมือสำหรับนักพัฒนาเว็บ คุณจะต้องอ้างอิงออบเจ็กต์ window
ของแผงเครื่องมือดังกล่าว
รับหน้าต่าง iframe ของแผงจากเครื่องจัดการเหตุการณ์ panel.onShown
onShown.addListener(function callback)
extensionPanel.onShown.addListener(function (extPanelWindow) {
extPanelWindow instanceof Window; // true
extPanelWindow.postMessage( // …
});
การส่งข้อความจากสคริปต์เนื้อหาไปยังหน้าเครื่องมือสำหรับนักพัฒนาเว็บ
การรับส่งข้อความระหว่างหน้าเครื่องมือสำหรับนักพัฒนาเว็บและสคริปต์เนื้อหาเกิดขึ้นโดยอ้อมผ่านทางหน้าพื้นหลัง
เมื่อส่งข้อความไปยังสคริปต์เนื้อหา หน้าพื้นหลังสามารถใช้เมธอด
tabs.sendMessage
ซึ่งจะกำหนดเส้นทางข้อความไปยังสคริปต์เนื้อหาในแท็บที่ต้องการ
ตามที่แสดงในการแทรกสคริปต์เนื้อหา
เมื่อส่งข้อความจากสคริปต์เนื้อหา จะไม่มีการส่งข้อความแบบสำเร็จรูป ลงในอินสแตนซ์หน้าเครื่องมือสำหรับนักพัฒนาเว็บที่ถูกต้องซึ่งเชื่อมโยงกับแท็บปัจจุบัน ในการแก้ไขเบื้องต้น คุณสามารถ หน้าเครื่องมือสำหรับนักพัฒนาเว็บจะสร้างการเชื่อมต่อที่ยั่งยืนกับหน้าพื้นหลัง และ หน้าเว็บพื้นหลังจะเก็บแผนที่ของรหัสแท็บไปยังการเชื่อมต่อ เพื่อให้สามารถกำหนดเส้นทางแต่ละข้อความไปยัง การเชื่อมต่อ
// background.js
var connections = {};
chrome.runtime.onConnect.addListener(function (port) {
var extensionListener = function (message, sender, sendResponse) {
// The original connection event doesn't include the tab ID of the
// DevTools page, so we need to send it explicitly.
if (message.name == "init") {
connections[message.tabId] = port;
return;
}
// other message handling
}
// Listen to messages sent from the DevTools page
port.onMessage.addListener(extensionListener);
port.onDisconnect.addListener(function(port) {
port.onMessage.removeListener(extensionListener);
var tabs = Object.keys(connections);
for (var i=0, len=tabs.length; i < len; i++) {
if (connections[tabs[i]] == port) {
delete connections[tabs[i]]
break;
}
}
});
});
// Receive message from content script and relay to the devTools page for the
// current tab
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
// Messages from content scripts should have sender.tab set
if (sender.tab) {
var tabId = sender.tab.id;
if (tabId in connections) {
connections[tabId].postMessage(request);
} else {
console.log("Tab not found in connection list.");
}
} else {
console.log("sender.tab not defined.");
}
return true;
});
หน้าเครื่องมือสำหรับนักพัฒนาเว็บ (หรือแผงหรือแผงแถบด้านข้าง) จะสร้างการเชื่อมต่อดังนี้
// Create a connection to the background page
var backgroundPageConnection = chrome.runtime.connect({
name: "panel"
});
backgroundPageConnection.postMessage({
name: 'init',
tabId: chrome.devtools.inspectedWindow.tabId
});
การรับส่งข้อความจากสคริปต์ที่แทรกไว้ไปยังหน้าเครื่องมือสำหรับนักพัฒนาเว็บ
แม้ว่าโซลูชันข้างต้นจะทำงานกับสคริปต์เนื้อหาได้ แต่โค้ดที่ถูกแทรกลงในหน้าเว็บโดยตรง
(เช่น ด้วยการเพิ่มแท็ก <script>
หรือผ่าน inspectedWindow.eval
)
กลยุทธ์ที่แตกต่างออกไป ในบริบทนี้ runtime.sendMessage
จะไม่ส่งข้อความไปที่
สคริปต์พื้นหลังตามที่คาดไว้
ในการแก้ปัญหาเฉพาะหน้า คุณสามารถรวมสคริปต์ที่แทรกไว้กับสคริปต์เนื้อหาที่ทำหน้าที่เป็น
ตัวกลาง หากต้องการส่งข้อความไปยังสคริปต์เนื้อหา คุณสามารถใช้window.postMessage
API ต่อไปนี้เป็นตัวอย่างโดยสมมติว่าสคริปต์พื้นหลังจากส่วนก่อนหน้า:
// injected-script.js
window.postMessage({
greeting: 'hello there!',
source: 'my-devtools-extension'
}, '*');
// content-script.js
window.addEventListener('message', function(event) {
// Only accept messages from the same frame
if (event.source !== window) {
return;
}
var message = event.data;
// Only accept messages that we know are ours
if (typeof message !== 'object' || message === null ||
!message.source === 'my-devtools-extension') {
return;
}
chrome.runtime.sendMessage(message);
});
ตอนนี้ข้อความจะส่งจากสคริปต์ที่แทรกไปยังสคริปต์เนื้อหาไปยังพื้นหลัง และสุดท้ายก็ไปที่หน้าเครื่องมือสำหรับนักพัฒนาเว็บ
คุณอาจพิจารณาเทคนิคการส่งข้อความทางเลือก 2 อย่างที่นี่ก็ได้
การตรวจจับเมื่อมีการเปิดและปิดเครื่องมือสำหรับนักพัฒนาเว็บ
หากส่วนขยายต้องการติดตามว่าหน้าต่างเครื่องมือสำหรับนักพัฒนาเว็บเปิดอยู่หรือไม่ คุณสามารถเพิ่ม onConnect Listener หน้าพื้นหลังและเรียกใช้ connect จากหน้าเครื่องมือสำหรับนักพัฒนาเว็บ เนื่องจากแต่ละแท็บสามารถ มีหน้าต่างเครื่องมือสำหรับนักพัฒนาเว็บเปิดอยู่ คุณอาจได้รับเหตุการณ์การเชื่อมต่อหลายรายการ ในการติดตามว่ามี หน้าต่างเครื่องมือสำหรับนักพัฒนาเว็บเปิดอยู่ คุณต้องนับเหตุการณ์การเชื่อมต่อและยกเลิกการเชื่อมต่อดังที่แสดงด้านล่าง
// background.js
var openCount = 0;
chrome.runtime.onConnect.addListener(function (port) {
if (port.name == "devtools-page") {
if (openCount == 0) {
alert("DevTools window opening.");
}
openCount++;
port.onDisconnect.addListener(function(port) {
openCount--;
if (openCount == 0) {
alert("Last DevTools window closing.");
}
});
}
});
หน้าเครื่องมือสำหรับนักพัฒนาเว็บจะสร้างการเชื่อมต่อดังนี้
// devtools.js
// Create a connection to the background page
var backgroundPageConnection = chrome.runtime.connect({
name: "devtools-page"
});
ตัวอย่างส่วนขยายเครื่องมือสำหรับนักพัฒนาเว็บ
เลือกซอร์สของตัวอย่างส่วนขยายเครื่องมือสำหรับนักพัฒนาเว็บเหล่านี้
- ส่วนขยาย Polymer Devtools - ใช้ตัวช่วยจำนวนมากที่ทำงานในหน้าโฮสต์เพื่อค้นหา DOM/JS เพื่อกลับไปยังแผงที่กำหนดเอง
- ส่วนขยาย React DevTools - ใช้โมดูลย่อยของ Blink เพื่อใช้คอมโพเนนต์ UI ของเครื่องมือสำหรับนักพัฒนาเว็บซ้ำ
- Ember Inspector - แกนส่วนขยายที่ใช้ร่วมกันกับอะแดปเตอร์สำหรับทั้ง Chrome และ Firefox
- Coquette-inspect - ส่วนขยายที่ใช้ React ที่ดูสะอาดตาซึ่งมีการแทรก Agent การแก้ไขข้อบกพร่องลงใน หน้าโฮสต์
- แกลเลอรีส่วนขยายเครื่องมือสำหรับนักพัฒนาเว็บและส่วนขยายตัวอย่างของเรามีแอปที่คุ้มค่ามากกว่าในการ ติดตั้ง ทดลองใช้ และเรียนรู้
ข้อมูลเพิ่มเติม
สำหรับข้อมูลเกี่ยวกับ API มาตรฐานที่ส่วนขยายสามารถใช้ได้ โปรดดู chrome* API และเว็บ API
แสดงความคิดเห็นให้เราทราบ ความคิดเห็นและคำแนะนำของคุณจะช่วยเราปรับปรุง API ให้ดียิ่งขึ้น
ตัวอย่าง
ดูตัวอย่างที่ใช้ API ของเครื่องมือสำหรับนักพัฒนาเว็บได้ในตัวอย่าง